207 Commits
v0.6 ... v0.7.5

Author SHA1 Message Date
lexluo09
86bf40c8fb (feature)(chat) optimized code in GroupByCorrector (#226) 2023-10-16 12:11:59 +08:00
lexluo09
f90ab22119 (feature)(chat) add aggregate to metric in GroupByCorrector (#225) 2023-10-16 10:45:40 +08:00
williamhliu
8e7d224b7b (feature)(webapp) modify chat sdk setupProxy config (#224)
* (feature)(webapp) use nativeQuery field to determine whether it is a selection

* (feature)(webapp) modify chat sdk version

* (feature)(webapp) modify setupProxy target

* (feature)(webapp) modify setupProxy target

* (feature)(webapp) modify setupProxy target

* (feature)(webapp) modify chat sdk setupProxy config
2023-10-14 17:31:19 +08:00
williamhliu
29925a90ca (feature)(webapp) modify chat sdk setupProxy config (#223) 2023-10-14 17:14:40 +08:00
williamhliu
fdf48d7bfd (feature)(webapp) use nativeQuery field to determine whether it is a selection (#222) 2023-10-14 16:37:28 +08:00
LXW
d9efe8f137 (improvement)(semantic) modify demo data to adapt to sql splicing (#221)
Co-authored-by: jolunoluo
2023-10-13 22:13:35 +08:00
lexluo09
6afb2f0914 (improvement)(chat) deal webapp copy in start (#220) 2023-10-13 21:11:05 +08:00
lexluo09
82ab9e3a6a (improvement)(chat) reduce log in build.sh and set dir in individual (#219) 2023-10-13 20:25:30 +08:00
lexluo09
f5ca33859c (improvement)(chat) remove setEnvToWeb in moveAllToRuntime (#218) 2023-10-13 19:58:54 +08:00
LXW
a0b4fb33c1 (improvement)(chat) solved query recall add embedding url check (#217)
Co-authored-by: jolunoluo
2023-10-13 19:53:22 +08:00
williamhliu
40705181a0 (fix)(webapp) fix the issue of missing agentId in the parameter passing of recommended similar questions in the history record (#216) 2023-10-13 19:43:18 +08:00
lexluo09
308178f299 (improvement)(project) update the changelog (update to 0.7.5) (#215) 2023-10-13 19:20:03 +08:00
lexluo09
410f2c93b9 (improvement)(chat) update version to 0.7.5 and reduce log in supersonic-daemon.sh (#214) 2023-10-13 19:16:31 +08:00
williamhliu
767abc2b90 (feature)(webapp) add filter modify and similar questions (#213) 2023-10-13 18:31:00 +08:00
lexluo09
ab19b18169 (improvement)(chat) fix supersonic sh set envToWeb (#212) 2023-10-13 17:54:36 +08:00
lexluo09
406fe995c9 (improvment)(chat) add relative path to supersonic-common.sh (#211) 2023-10-13 17:32:29 +08:00
lexluo09
151963ea79 (improvement)(chat) support nested query sql (#210) 2023-10-13 17:24:10 +08:00
lexluo09
5583426115 (improvement)(chat) optimize start stop build scripts and the runtime dir does not exist move all to runtime (#209) 2023-10-13 16:32:59 +08:00
LXW
9d1707eba1 (improvement)(script) build runtime directory in supersonic-daemon.bat (#208)
Co-authored-by: jolunoluo
2023-10-13 15:34:27 +08:00
lexluo09
f605cf0ef9 (improvment)(chat) if exist count() in dsl,set query to NATIVE and only order by field and group by field can add to select (#206) 2023-10-13 14:25:24 +08:00
LXW
119e5b8c58 (improvement)(chat) solved query code compatible with checkstyle (#205)
Co-authored-by: jolunoluo
2023-10-13 13:27:46 +08:00
lexluo09
de764f3353 (improvment)(chat) refactor the jsqlparser code (#204) 2023-10-13 11:45:04 +08:00
LXW
e4280e5516 (improvment)(chat) semantic parse info dimension filters support UNION and AND splicing methods (#203)
Co-authored-by: jolunoluo
2023-10-13 11:33:03 +08:00
LXW
886ee32e2f (improvment)(chat) remove low-scoring queries from recommended questions (#202)
Co-authored-by: jolunoluo
2023-10-13 11:17:52 +08:00
LXW
7544780ff7 (improvment)(chat) remove the parse in candidate parse that has the same score as selectparse (#201)
Co-authored-by: jolunoluo
2023-10-13 10:05:51 +08:00
mainmain
26beff1080 (improvement)(chat) dsl supports revision (#200) 2023-10-12 21:45:40 +08:00
LXW
88b8130d37 (improvment)(semantic) dimension and metric list support alias and createdBy query (#199)
Co-authored-by: jolunoluo
2023-10-12 17:12:12 +08:00
LXW
e7b8c68dba (improvment)(chat) optimize parse performance (#197)
* (improvment)(chat) optimize parse performance
---------

Co-authored-by: jolunoluo
2023-10-12 11:51:57 +08:00
lexluo09
b753eda9b9 (improvement)(chat) set native value in parser and execute , optimized the executeDirectQuery code (#196) 2023-10-12 11:38:48 +08:00
lexluo09
e6f2ce2598 (improvement)(chat) if there is no group by in dsl,set MetricTable's aggOption to NATIVE (#195) 2023-10-11 23:51:09 +08:00
lexluo09
a191bbbf6e (improvement)(chat) update load bench mark demo - to _ (#194) 2023-10-11 15:17:13 +08:00
jipeli
65f48dd789 Merge pull request #193 from jipeli/master
(improvement)(semantic) metric table add agg option
2023-10-11 14:51:46 +08:00
jipengli
c14d4e59d4 (improvement)(semantic) metric table add agg option 2023-10-11 14:45:20 +08:00
lexluo09
6b2a14e589 (improvement)(chat) The group by field can be added even if the group by field already exists (#192) 2023-10-11 13:14:42 +08:00
lexluo09
d6cefaa6d2 (improvement)(chat) If the number of aggregated fields is equal to the number of queried fields, do not add fields to select (#191) 2023-10-11 11:08:45 +08:00
mainmain
278af3ce34 (improvement)(chat) dsl supports revision and fix queryDimensionValue performance (#188) 2023-10-10 21:28:42 +08:00
lexluo09
3b1cbd4fd7 (improvement)(chat) group by corrector remove aggregate fields (#186) 2023-10-10 17:42:19 +08:00
lexluo09
500652da36 (improvement)(chat) support add parenthesis and add arenthesis in sys_imp_date (#184) 2023-10-10 16:13:48 +08:00
lexluo09
eee39f56a8 (improvement)(chat) support updateFieldValueByLinkingValue and fix EntityListQuery NullPointerException (#182) 2023-10-10 11:16:52 +08:00
lexluo09
719b797037 (improvement)(chat) support remove InExpression and partly complete fillResponse if queryResults exist primaryEntityBizName (#181) 2023-10-09 18:07:14 +08:00
Bowen Liang
7cb8208065 use default python and pip (#178) 2023-10-09 15:28:20 +08:00
Bowen Liang
a03ababc80 show commands in scripts (#177) 2023-10-09 15:26:01 +08:00
jerryjzhang
a3565a0ae9 [improvement][docs]Update README to add wechat account 2023-10-09 14:11:45 +08:00
jipeli
07a64375ce Merge pull request #179 from jipeli/master
(improvement)(semantic) fixed queryBySql execute error on mysql <=5.7
2023-10-09 12:02:19 +08:00
jipengli
ec1e63e2f2 (improvement)(semantic) fixed queryBySql execute error on mysql <=5.7 2023-10-09 12:00:25 +08:00
lexluo09
8487966888 (improvement)(chat) suppoprt show having filter and sum(metirc) filter (#176) 2023-10-08 21:46:49 +08:00
codescracker
4bbd2c7446 Features that allow user to config LLM by config file. (#174) 2023-10-08 19:35:22 +08:00
lexluo09
d9bab899fe (improvement)(chat) remove space before function in semantic parser (#175) 2023-10-08 18:24:18 +08:00
jerryjzhang
e3b3e8861d [improvement][docs]Update README to improve motivation part 2023-10-08 14:08:48 +08:00
LXW
69242f9f2d (improvement)(chat) add responder to fill additional information, such as  entity information (#173)
* (improvement)(chat) add responder to fill additional information, such as  entity information

---------

Co-authored-by: jolunoluo
2023-10-08 12:00:28 +08:00
jerryjzhang
a21c7bce40 [improvement][docs]Update README to improve motivation part 2023-10-08 11:01:27 +08:00
lexluo09
7379e3a833 (improvement)(chat) remove check llmParser error than exit (#172) 2023-10-08 10:14:17 +08:00
jerryjzhang
b565b9c4e5 [improvement][chat]Rename SemanticLayer to SemanticInterpreter 2023-10-08 09:33:41 +08:00
lexluo09
99ac17a5e4 (improvement)(chat) fix check llmParser health error if not install jq (#171) 2023-10-07 22:07:14 +08:00
lexluo09
4ccee8b107 (improvement)(chat) support remove where condition and fix simplifySql space error and addAggregateToMetric optimize (#170) 2023-10-07 21:51:37 +08:00
jerryjzhang
eccd791a39 [improvement][docs]Update README and wechat group 2023-10-07 16:48:35 +08:00
LXW
3d6878fe9f (improvement)(script) optimize bat script encoding (#168)
* (improvement)(script) optimize bat script encoding

---------

Co-authored-by: jolunoluo
2023-10-07 12:00:33 +08:00
Bowen Liang
1e1803d148 Inroduce Loguru for Python logging (#151)
* add loguru to pip requirements

* init logger

* use logger
2023-10-07 10:42:02 +08:00
Scott
343995fd8f (improve)add health check to python service (#167) 2023-10-07 10:40:34 +08:00
williamhliu
71cb20eb4f Integrate Chat and Copilot into chat-sdk, and add SQL parse display (#166) 2023-10-02 18:05:12 +08:00
lexluo09
741ed4191b (improvement)(chat) support show sum metric in chinese name and support multiple conditions in having and if not exist metirc than not addAggregateToMetric (#165) 2023-09-30 23:35:58 +08:00
lexluo09
2a6391a2ee (improvement)(chat) add metric aggregate only in select not exit metirc (#164) 2023-09-28 17:59:37 +08:00
LXW
405e846a0e (improvement)(script) update bat script (#163)
* (improvement)(script) update bat script

---------

Co-authored-by: jolunoluo
2023-09-28 12:05:16 +08:00
lexluo09
155cf22841 (improvement)(chat) remove tableCorrector and add replaceFieldNameByValue test (#162) 2023-09-27 21:03:40 +08:00
mainmain
e688422ec3 (improvement)(semantic) perfect dsl permission (#161) 2023-09-27 21:01:44 +08:00
codescracker
6047c787b3 1. upgrade text2sql for absolute time related expression in query. 2. add feature of resolved queries retrieval. (#160) 2023-09-27 18:46:03 +08:00
LXW
c03166b622 (improvement)(doc) remove sql.ddl in semantic and chat (#158)
Co-authored-by: jolunoluo
2023-09-27 18:16:35 +08:00
lexluo09
617db611c3 (improvement)(chat) logic sql show in chinese and convert to bizName in execute (#156) 2023-09-27 17:27:31 +08:00
lexluo09
f931951ad5 (improvement)(chat) support corrector fieldName by fieldValue in like (#153) 2023-09-27 14:13:13 +08:00
lexluo09
df7fea9ee3 (improvement)(chat) add addAggregateToMetric in GlobalAfterCorrector and fix getAgg null (#152) 2023-09-27 12:55:59 +08:00
lexluo09
24e8e756de (improvement)(chat) add default aggregate to all metric and add group by to dimension and add metric filter in having (#150) 2023-09-27 00:05:45 +08:00
LXW
ff5479f1a2 add metric and dimension name check (#149)
* (improvement)(semantic) add metric and dimension name check

* (improvement)(chat) opt QueryResponder recalling history similar solved query

---------

Co-authored-by: jolunoluo
2023-09-26 20:17:52 +08:00
lexluo09
4ad3e1d9cf (improvement)(chat) support show logicSql querySql llmParseSql (#148) 2023-09-26 20:17:02 +08:00
LXW
e4af83380b Merge pull request #147 from lxwcodemonkey/master
(improvement)(doc) update readme
2023-09-26 17:46:44 +08:00
jolunoluo
d30fe53ef3 (improvement)(doc) update readme 2023-09-26 17:45:33 +08:00
Bowen Liang
9e0abc60be (feat)(llm) expose config for Open API base url (#112) 2023-09-26 11:45:09 +08:00
Bowen Liang
dc33cdce5a remove unused imports in Python (#145) 2023-09-26 11:43:57 +08:00
Bowen Liang
f5b8690ce0 (improvement) Support PIP_PATH and PYTHON_PATH env var for building and starting services (#146) 2023-09-26 11:42:55 +08:00
jerryjzhang
fbb67f54ab [improvement][docs]Update README and wechat group 2023-09-26 09:57:35 +08:00
lexluo09
5c4e80c8f8 (improvement)(chat) filter nature throw detectModelIds in mapper and add loginSql (#144) 2023-09-25 21:56:47 +08:00
LXW
0774c35589 Merge pull request #143 from lxwcodemonkey/master
(improvement)(common) increase http connection time
2023-09-25 21:30:40 +08:00
jolunoluo
553963a10a (improvement)(common) increase http connection time 2023-09-25 21:29:30 +08:00
LXW
0bf171c8a6 Merge pull request #142 from lxwcodemonkey/feature/lxw
(improvement)(chat) add QueryResponder to recall history similar solved query
2023-09-25 21:20:51 +08:00
jolunoluo
f5549f7430 Merge branch 'master' into feature/lxw 2023-09-25 21:17:03 +08:00
jolunoluo
34816451c0 (improvement)(chat) recall history solved query in every parse 2023-09-25 21:09:43 +08:00
jolunoluo
e1772c25c4 Merge branch 'feature/showcase' into feature/lxw
# Conflicts:
#	chat/core/src/main/java/com/tencent/supersonic/chat/service/impl/QueryServiceImpl.java
#	chat/core/src/main/resources/mapper/ChatQueryDOMapper.xml
2023-09-25 16:59:31 +08:00
jolunoluo
65653c0ee2 (improvement)(chat) save agentId in history query 2023-09-25 16:54:36 +08:00
lexluo09
3addfb9a87 (improvement)(common) support addAggregateToField and addGroupBy and convert metricFilter to Having (#140) 2023-09-25 16:18:58 +08:00
LXW
67be01f504 Merge pull request #139 from lxwcodemonkey/feature/modelDemoData
Feature/create model and benchmark demo data through api instead of data-h2.sql
2023-09-25 15:33:20 +08:00
jolunoluo
99aa7c9433 Merge branch 'master' into feature/modelDemoData 2023-09-25 15:17:21 +08:00
jolunoluo
ccfdec8b45 (improvement)(semantic) create model demo data through api instead of data-h2.sql
(improvement)(semantic) create benchmark demo data through api instead of data-h2.sql
2023-09-25 15:16:14 +08:00
Bowen Liang
dbd259adb0 (chore)(sytle) Apply Python styling by black via spotless maven plugin (#113)
* introduce spotless maven plugin with Python black for styling
2023-09-25 10:57:14 +08:00
LXW
ec151d7b53 Merge pull request #132 from lxwcodemonkey/feature/removeImagesInDocs
(improvement)(docs) remove useless user guides
2023-09-23 22:01:14 +08:00
jolunoluo
5fbb1927a4 (improvement)(docs) remove useless user guides 2023-09-23 21:57:58 +08:00
LXW
3bc13642af Merge pull request #131 from lxwcodemonkey/feature/removeImagesInDocs
(improvement)(docs) remove useless images
2023-09-22 22:26:19 +08:00
jolunoluo
6b38a4f602 (improvement)(docs) remove useless images 2023-09-22 22:24:05 +08:00
jolunoluo
51f62438cf (improvement)(chat) add QueryResponder to recall history similar solved query 2023-09-22 14:52:53 +08:00
jolunoluo
9d8b54072a Merge branch 'master' into feature/lxw 2023-09-22 10:01:33 +08:00
mainmain
0982c013d1 [improvement](chat) dsl dimensionfilter can revise and add dsl permission (#118) 2023-09-21 21:57:26 +08:00
lexluo09
03a4719aed [improvement][chat]llm parser corrector is simplified by sql distribution (#120) 2023-09-21 21:57:06 +08:00
jerryjzhang
5c3fd75ed4 [improvement][docs]Update wechat group 2023-09-21 11:37:23 +08:00
jipeli
6dfc728b5b support foreign identify (#111)
* [improvement][semantic] add get metric agg function

* [improvement][semantic] support foreign identify
2023-09-20 22:20:00 +08:00
jipeli
071ef8432e [improvement][semantic] add get metric agg function (#110) 2023-09-20 21:39:59 +08:00
jolunoluo
8ad5ffe20f Merge remote-tracking branch 'origin/master' 2023-09-20 17:03:04 +08:00
LXW
49ba0e3f41 (feature)support adding tag for metric and support super admin configuration (#108) 2023-09-20 17:00:38 +08:00
tristanliu
5a42ff4b78 [improvement][semantic-fe] metric market experience optimization (#109)
* [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab.
[improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions.
[improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager.

* [improvement][semantic-fe] Add time granularity setting in the data source configuration.

* [improvement][semantic-fe] Dictionary import for dimension values supported in Q&A visibility

* [improvement][semantic-fe] Modification of data source creation prompt wording"

* [improvement][semantic-fe] metric market experience optimization
2023-09-20 16:58:57 +08:00
jolunoluo
20472dce88 Merge branch 'master' into feature/metricAddTag 2023-09-20 16:44:15 +08:00
Scott
057a7c9c6d fix:set script file executable (#107) 2023-09-20 16:26:03 +08:00
jolunoluo
63eff5c62a (improvement)(semantic) add admin auth check in metric market 2023-09-20 16:10:04 +08:00
jolunoluo
b824cd8ce7 (improvement)(auth) support super admin configuration 2023-09-20 16:09:46 +08:00
lexluo09
eee82dea07 (improvement)(project) dsl support get topN dimension/metric filter by modelId (#106) 2023-09-20 12:09:42 +08:00
lexluo09
98656eb445 (improvement)(project) dsl support get topN dimension/metric by useCount and fix semanticService get dimension/metric usrCount error (#105) 2023-09-20 11:21:50 +08:00
codescracker
c8ff37e304 (improvement)(text2sql) add text2sql feature that only call LLM once, and add correponding configs and docs. (#102)
Co-authored-by: shaoweigong <shaoweigong@tencent.com>
2023-09-20 10:22:20 +08:00
jolunoluo
3fe726ac23 (improvement)(semantic) support adding tag for metric 2023-09-19 23:51:24 +08:00
jolunoluo
d5a253a781 (improvement)(chat) add QueryResponder to recall history similar solved query 2023-09-19 21:08:41 +08:00
williamhliu
6a5a95e543 [fix](webapp) fix front end package version issues (#104) 2023-09-19 19:23:00 +08:00
lexluo09
a94a44826b (improvement)(project) support explain in semantic and show explain sql in web and fix chat start error (#103) 2023-09-19 16:38:24 +08:00
jolunoluo
31c8fea2dc (improvement)(chat) add QueryResponder to recall history similar solved query 2023-09-19 15:44:01 +08:00
tristanliu
13dcf0edb9 [improvement][semantic-fe] Modification of data source creation prompt wording (#100)
* [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab.
[improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions.
[improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager.

* [improvement][semantic-fe] Add time granularity setting in the data source configuration.

* [improvement][semantic-fe] Dictionary import for dimension values supported in Q&A visibility

* [improvement][semantic-fe] Modification of data source creation prompt wording"
2023-09-19 11:25:16 +08:00
LXW
7bc64bc53b (fix)(semantic) fix database db name modify error (#99) 2023-09-19 09:11:14 +08:00
daikon
4991efe50c [chat](fix) fix system default metric fetch wrong datasourceBizName (#98) 2023-09-19 09:11:01 +08:00
lexluo09
a87304b22b (improvement)(chat) dsl corrector support add agg metric in having (#95) 2023-09-15 17:54:51 +08:00
lexluo09
3701ade05f (improvement)(chat) dsl parser and corrector support having function (#94) 2023-09-15 15:38:33 +08:00
lexluo09
45ed5648c4 (improvement)(project) support move webapp to chat/semantic/standalone class and copy to runtime in build (#93) 2023-09-15 15:09:42 +08:00
lexluo09
682d35b2b2 (improvement)(chat) update llm url to llmParser in chat project (#92) 2023-09-14 22:59:11 +08:00
lexluo09
30f5fc9ab1 (improvement)(project) rename llm to llmParser and optimizing python start scripts and optimizing and optimizing build/start scripts (#91) 2023-09-14 22:30:06 +08:00
LXW
bc69d2221a (improvement)(semantic) support dimension value query in SemanticLayer (#90) 2023-09-14 14:01:51 +08:00
daikon
592870f397 [knowledge](improve) add knowledge base dimension value task manage (#88) 2023-09-14 14:01:38 +08:00
tristanliu
157c2999dc [improvement][semantic-fe] Dictionary import for dimension values supported in Q&A visibility (#89)
* [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab.
[improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions.
[improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager.

* [improvement][semantic-fe] Add time granularity setting in the data source configuration.

* [improvement][semantic-fe] Dictionary import for dimension values supported in Q&A visibility
2023-09-14 12:14:02 +08:00
jerryjzhang
b6d984475c [improvement][launcher]Rename service and binary names 2023-09-14 10:06:43 +08:00
lexluo09
6a98ce9d28 (improvement)(chat) remove domain in wordservice and the model id takes precedence over the number of model aliases (#87) 2023-09-13 21:25:31 +08:00
LXW
c802c508fb (improvement)(build)modify the compressed package name from supersonic-standalone.tar.gz to supersonic.tar.gz (#86) 2023-09-13 18:38:16 +08:00
codescracker
545fb139ee Allow user to config examples and number of examples used by text2sql in middle of run (#85) 2023-09-13 17:24:12 +08:00
williamhliu
c38507d50c [improvement](webapp) optimize drill down dimensions (#84) 2023-09-13 15:05:23 +08:00
lexluo09
c8b5c0f3a3 (improvement) remove separate shell and support start llmParser service (#83) 2023-09-13 14:32:41 +08:00
mainmain
ef30e7a5b8 [improvement] alter script (#82) 2023-09-13 14:02:02 +08:00
LXW
12417c66cd (improvement) simplify build and start script (#81) 2023-09-13 11:31:07 +08:00
lexluo09
f00da45824 (improvement)(chat) remove FunctionAliasReplaceVisitor in chat config (#80) 2023-09-12 20:20:10 +08:00
lexluo09
8d8440f724 (improvement)(chat) add FunctionAliasCorrector in dsl corrector (#79) 2023-09-12 17:30:53 +08:00
williamhliu
55138986ed [feature](webapp) add a minimize button for copilot (#78) 2023-09-12 17:10:43 +08:00
lexluo09
2c621a1338 (improvement)(chat) remove group by dimension and add FunctionAliasReplaceVisitor in dsl (#77)
* (improvement)(chat) remove group by dimension in join case

* (improvement)(chat) add FunctionAliasReplaceVisitor in dsl

---------
2023-09-12 17:10:43 +08:00
jerryjzhang
c6b87d30a5 [improvement][docs]Move "how to build" chapter to project wiki 2023-09-12 17:09:23 +08:00
williamhliu
8c5c7c2e32 [feature](webapp) add dsl query fields (#75) 2023-09-12 14:29:26 +08:00
lexluo09
7fce9bacc2 (improvement)(chat) two display modes are supported in dsl: group by and details (#74) 2023-09-12 13:21:23 +08:00
lexluo09
8aedfbb6a0 (improvement)(chat) support llm default modelId and fix delete agent tool error (#73) 2023-09-11 23:46:08 +08:00
mainmain
eca92d2493 [fix](chat) fix visibility when searching (#72) 2023-09-11 18:05:24 +08:00
lexluo09
a4fc11887c (improvement)(chat) support add model aliasList to dict and update domainName to modelName (#71) 2023-09-11 13:03:03 +08:00
tristanliu
e4b0129fba [improvement][semantic-fe] Add time granularity setting in the data source configuration. (#70)
* [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab.
[improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions.
[improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager.

* [improvement][semantic-fe] Add time granularity setting in the data source configuration.
2023-09-11 12:26:04 +08:00
LXW
76e8d253b1 [improvement](config) add bat script for standalone start and llm start (#69) 2023-09-11 10:47:36 +08:00
lexluo09
d173924efd (improvement)(chat)the DslTool is configured on the agent by default (#68) 2023-09-11 10:30:51 +08:00
daikon
465416e30c [release](project)update revision to 0.7.4 (#67) 2023-09-10 22:32:32 +08:00
daikon
a8add4c013 [release](project)update version 0.7.4 backend (#66) 2023-09-10 21:26:46 +08:00
williamhliu
02068f58c7 [feature](chat-sdk) add @ant-design/icons dependency (#65) 2023-09-10 19:51:18 +08:00
williamhliu
3c0edb67c7 [feature](webapp) add mobile agents drawer (#64) 2023-09-10 11:50:26 +08:00
tristanliu
5bab18e092 [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab. (#63)
[improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions.
[improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager.
2023-09-09 18:36:54 +08:00
LXW
71d9f9c9e9 [improvement](config) Add a switch to load the demo and update schema-mysql.sql 2023-09-08 17:00:18 +08:00
williamhliu
90f6a20516 [feature](webapp) add script command to accommodate different Node.js versions and change lerna + npm to pnpm workspaces (#61) 2023-09-07 21:29:13 +08:00
jerryjzhang
898108d7e1 [improvement][docs]Add wiki link to README 2023-09-07 21:04:27 +08:00
lexluo09
728e7647dc add llm default url config and add pandas in requirements.txt (#59) 2023-09-07 11:14:44 +08:00
jerryjzhang
ac0f7ea982 [docs]update wechat contact 2023-09-07 09:00:58 +08:00
SunDean
20d7941d57 (improvement)(doc) remove user guide in doc directory and update user guide images (#58) 2023-09-06 22:38:22 +08:00
SunDean
ddcdd99188 (improvement)(doc) update user guide images (#57) 2023-09-06 21:33:27 +08:00
williamhliu
9267f8ed18 [fix](supersonic-fe) fix the issue of agent metric interpret value display (#56)
* [fix](supersonic-fe) fix the issue of agent metric interpret value display
2023-09-05 12:00:00 +08:00
jerryjzhang
249728919d [improvement][docs]update README and demo video 2023-09-04 16:33:03 +08:00
williamhliu
f3f84ab9af [improvement](webapp) optimize agent background color and remove entity metric tip (#54)
* [improvement](webapp) optimize agent background color and remove entity metric tip
2023-09-04 16:26:58 +08:00
jerryjzhang
90e62ddccc [improvement](webapp) optimize filter css styles and modify menu name
Co-authored-by: williamhliu <williamhliu@tencent.com>
2023-09-04 15:35:17 +08:00
tristanliu
fbd145fd92 Merge pull request #50 from sevenliu1896/master
[improvement][semantic-fe] Refactor database settings functionality.
2023-09-04 12:36:03 +08:00
tristanliu
f5a7068d5e [improvement][semantic-fe] Refactor database settings functionality. 2023-09-04 12:29:07 +08:00
williamhliu
d5c5c63a75 [feature](webapp) upgrade agent 2023-09-04 11:46:36 +08:00
lexluo09
559ef974b0 (improvement)(project) support for modifying filter conditions and fix group by pushdown and add windows scipt (#49)
Co-authored-by: lexluo <lexluo@tencent.com>
2023-09-03 23:51:47 +08:00
SunDean
8440f1f30e (improvement)(build) add bat scripts for deployment on windows (#46) 2023-09-01 10:23:57 +08:00
jerryjzhang
728235907d [improvement][docs]update demo video and wechat contact 2023-08-31 20:24:24 +08:00
williamhliu
40e0a58502 [feature](project) delete package-lock.json (#44)
Co-authored-by: williamhliu <williamhliu@tencent.com>
2023-08-30 14:19:39 +08:00
lexluo09
9723c2496e [release][project]update mvn pom to 0.7.3 and recover llm code,start shell, and docs (#43)
Co-authored-by: lexluo <lexluo@tencent.com>
2023-08-30 14:18:52 +08:00
williamhliu
4b99736a38 Merge pull request #42 from williamhliu/master
[feature](webapp) merge query steps to one card
2023-08-29 22:16:35 +08:00
williamhliu
36fd737440 [feature](webapp) merge query steps to one card 2023-08-29 22:14:14 +08:00
mainmain
93ca060c45 [improvement] fix LLMDslParser name problem (#41)
Co-authored-by: zuopengge <hwzuopengge@tencent.com>
2023-08-29 22:00:40 +08:00
mainmain
e1911bc81b [release][project] supersonic 0.7.3 version backend update (#40)
* [improvement] add some features

* [improvement] revise CHANGELOG

---------

Co-authored-by: zuopengge <hwzuopengge@tencent.com>
2023-08-29 20:06:34 +08:00
jerryjzhang
6fe9ab79ed [improvement][docs]Add local development build to README 2023-08-29 18:23:12 +08:00
jerryjzhang
5ee5ab116f [improvement][docs]Add wechat contact to README 2023-08-29 09:53:33 +08:00
Scott
a6c4d10d70 [improvement][project]update scripts to build&run on macos (#37)
* [improvement][project]update scripts to build&run on macos
2023-08-28 19:05:17 +08:00
codescracker
0d65d03bee upgrade text2dsl module for date related parse. (#38)
* [improvement](llm) data de-identification for few-shots examples.

* [improvement](llm) add plugin-call and preset retrieval features.

* [fix](llm) remove config variables.

* [improvement][feature]upgrade text2dsl module for date related parse.

---------
2023-08-28 18:56:24 +08:00
jerryjzhang
acca5e4538 [improvement][docs]update README and architecture diagram 2023-08-28 11:46:07 +08:00
williamhliu
233899ca3e Merge pull request #35 from williamhliu/master
[feature](weaapp) add agent
2023-08-20 18:47:39 +08:00
williamhliu
aa218898ff [feature](weaapp) add agent 2023-08-20 18:17:00 +08:00
mainmain
cf1b5336c3 [improvement](supersonic) based on version 0.7.2 (#34)
Co-authored-by: zuopengge <hwzuopengge@tencent.com>
2023-08-20 17:30:35 +08:00
lexluo09
c93e60ced7 [improvement][project] update version to 0.7.2 (#32)
Co-authored-by: lexluo <lexluo@tencent.com>
2023-08-15 20:38:11 +08:00
williamhliu
3cb8f53aec Merge pull request #31 from williamhliu/master
[feature](webapp) add copilot and modify domain to model
2023-08-15 20:11:12 +08:00
williamhliu
86b93876c7 [feature](webapp) add copilot and modify domain to model 2023-08-15 20:04:04 +08:00
lexluo09
2732d8fee1 [fix](chat) add env bash to env.sh (#30)
Co-authored-by: lexluo <lexluo@tencent.com>
2023-08-15 18:08:45 +08:00
tristanliu
6c7c1ffbeb Merge pull request #29 from sevenliu1896/master
[improvement][semantic-fe] Restructured the code to extract the quest…
2023-08-15 10:43:14 +08:00
tristanliu
c3d3b1146b [improvement][semantic-fe] Restructured the code to extract the question-answer settings and model management model controls into the OverviewContainer component. 2023-08-15 10:40:58 +08:00
jipeli
b1952d64ab [improvement][project] supersonic 0.7.2 version backend update (#28)
Co-authored-by: jipengli <jipengli@tencent.com>
2023-08-15 08:56:18 +08:00
tristanliu
27283001a8 Merge pull request #26 from sevenliu1896/master
[improvement][semantic-fe] Optimized the frontend display and code lo…
2023-08-07 11:44:18 +08:00
tristanliu
ef7c37a8da [improvement][semantic-fe] Optimized the frontend display and code logic of visual modeling, and updated the relevant interface of the permission management module. 2023-08-07 10:10:54 +08:00
SunDean
aa0a100a85 [improvement][project] supersonic 0.7.0 version backend update (#24)
* [improvement][project] supersonic 0.7.0 version backend update

* [improvement][project] supersonic 0.7.0 version backend update

* [improvement][project] supersonic 0.7.0 version readme update

---------

Co-authored-by: jolunoluo <jolunoluo@tencent.com>
2023-08-05 22:17:56 +08:00
williamhliu
6951eada9d add chat plugin and split query to parse and execute (#25)
* [feature](webapp) add drill down dimensions and metric period compare and modify layout

* [feature](webapp) add drill down dimensions and metric period compare and modify layout

* [feature](webapp) gitignore add supersonic-webapp

* [feature](webapp) gitignore add supersonic-webapp

* [feature](webapp) add chat plugin and split query to parse and execute

* [feature](webapp) add chat plugin and split query to parse and execute

* [feature](webapp) add chat plugin and split query to parse and execute

---------

Co-authored-by: williamhliu <williamhliu@tencent.com>
2023-08-05 22:17:42 +08:00
jerryjzhang
c9baed6c4e [improvement][docs]update README and architecture diagram 2023-08-04 14:38:16 +08:00
jerryjzhang
4693785738 Merge remote-tracking branch 'origin/master' 2023-07-31 20:16:08 +08:00
jerryjzhang
a0a466fe07 [improvement][docs]update demo gif 2023-07-31 20:15:51 +08:00
jerryjzhang
23f3d50796 [improvement][docs]update README and architecture diagram 2023-07-31 17:32:39 +08:00
williamhliu
bdae7ebefa gitignore file add supersonic-webapp (#23)
* [feature](webapp) add drill down dimensions and metric period compare and modify layout

* [feature](webapp) add drill down dimensions and metric period compare and modify layout

* [feature](webapp) gitignore add supersonic-webapp

* [feature](webapp) gitignore add supersonic-webapp

---------

Co-authored-by: williamhliu <williamhliu@tencent.com>
2023-07-31 17:31:52 +08:00
williamhliu
7c99829052 add drill down dimensions and metric period compare and modify layout (#22)
* [feature](webapp) add drill down dimensions and metric period compare and modify layout

* [feature](webapp) add drill down dimensions and metric period compare and modify layout

---------

Co-authored-by: williamhliu <williamhliu@tencent.com>
2023-07-31 12:00:39 +08:00
tristanliu
0ac652c5d9 semantic-fe visual modeling pr (#21)
* [improvement][semantic-fe] Added an editing component to set filtering rules for Q&A. Now, the SQL editor will be accompanied by a list for display and control, to resolve ambiguity when using comma-separated values.
[improvement][semantic-fe] Improved validation logic and prompt copywriting for data source/dimension/metric editing and creation.
[improvement][semantic-fe] Improved user experience for visual modeling. Now, when using the legend to control the display/hide of data sources and their associated metric dimensions, the canvas will be re-layout based on the activated data source in the legend.

* [improvement][semantic-fe] Submitted a new version of the visual modeling tool.
[improvement][semantic-fe] Fixed an issue with the initialization of YoY and MoM metrics in Q&A settings.
[improvement][semantic-fe] Added a version field to the database settings.
[improvement][semantic-fe] 1. Added the ability to set YoY and MoM metrics in Q&A settings.2. Moved dimension value editing from the dimension editing window to the dimension list.

---------

Co-authored-by: tristanliu <tristanliu@tencent.com>
2023-07-31 11:23:37 +08:00
daikon
e2b2d31429 [improvement][project] supersonic 0.7.0 version backend update (#20)
Co-authored-by: kanedai <kanedai@tencent.com>
2023-07-31 11:09:58 +08:00
tristanliu
078a81038f [improvement][semantic-fe] Added an editing component to set filtering rules for Q&A. Now, the SQL editor will be accompanied by a list for display and control, to resolve ambiguity when using comma-separated values.
[improvement][semantic-fe] Improved validation logic and prompt copywriting for data source/dimension/metric editing and creation.
[improvement][semantic-fe] Improved user experience for visual modeling. Now, when using the legend to control the display/hide of data sources and their associated metric dimensions, the canvas will be re-layout based on the activated data source in the legend.

Co-authored-by: tristanliu <tristanliu@tencent.com>
2023-07-21 15:30:38 +08:00
codescracker
6492316e23 [improvement](llm) data de-identification for few-shots examples. (#17)
Co-authored-by: shaoweigong <shaoweigong@tencent.com>
2023-07-17 20:36:31 +08:00
1271 changed files with 80318 additions and 31286 deletions

3
.gitignore vendored
View File

@@ -15,3 +15,6 @@ assembly/runtime/*
/assembly/deploy
/runtime
**/.flattened-pom.xml
chm_db/
__pycache__/
/dict

View File

@@ -1,21 +0,0 @@
davinci 0.3.0 change log
1) add data portal
2) add metric trend chart
3) add feedback component
4) add tab component
5) add page setting
6) modify permission process
7) optimize css style
8) optimize filter
9) delete view module
supersonic 0.6.0 change log
1) add llm parser and llm api server
2) support fuzzy mapping
3) support query filter and domain filter in query and search
4) support standalone mode
5) add dsl query in semantic
6) code architecture adjustment in semantic and chat
7) add unit testing and integration testing
8) support dimension and metric alias

160
CHANGELOG.md Normal file
View File

@@ -0,0 +1,160 @@
# SuperSonic Changelog
- All notable changes to this project will be documented in this file.
- "Breaking Changes" describes any changes that may break existing functionality or cause
compatibility issues with previous versions.
## SuperSonic [0.7.5] - 2023-10-13
### Added
- add SQL generation improvement optimization, support LLM SQL, Logic SQL, and Physical SQL display.
- add showcase functionality to support recommending similar questions.
- add frontend modification of filtering conditions and re-querying feature.
- support nested query functionality in semantic.
- support switching queries between multiple parsers in the frontend.
### Updated
- optimizing the build and deployment of the project.
- overall optimization of the SQL Corrector functionality.
### Fixed
- fix execute error on mysql <=5.7
## SuperSonic [0.7.4] - 2023-09-10
### Added
- add llm parser config
- add datasource agg_time option
- add function name adaptor in clickhouse
- add dimension and metric show in dsl
### Updated
- update user guide doc
- update query building of plugin in default model
- update some core API constructs to keep naming consistency
- update ConfigureDemo config
- update the association mechanism so that invisible dimensions and metrics will no longer be associated
### Fixed
- fix hasAggregateFunction logic in SqlParserSelectHelper
## SuperSonic [0.7.3] - 2023-08-29
### Added
- meet checkstyle code requirements
- save parseInfo after parsing
- add time statistics
- add agent
### Updated
- dsl where condition is used for front-end display
- dsl remove context inheritance
## SuperSonic [0.7.2] - 2023-08-12
### Added
- Support asynchronous query - return parse information to user before executing result
- Add Model as the basic data structure of the semantic definitions - this will repalce the old conception of subdomain
### Updated
- improve knowledge word similarity algorithm
- improve embedding plugin chooser
- improve DSLQuery field correction and parser
### Fixed
- Fix mapper error that detectWord text is shorter than word
- Fix MetricDomainQuery inherit context
## SuperSonic [0.7.0] - 2023-07-30
### Added
- Add function call parser and embedding recall parser
- Add plugin management
- Add web page query and web service query
- Metric filter query support querying metrics and comparing them in different dimensions
- Support dimension value mapping
- Support dimension/metric invisible, chat filter related data
- Add user guide docs
### Fixed
- Fix the data problem of getDomainList interface in standalone mode
## SuperSonic [0.6.0] - 2023-07-16
### Added
- Support llm parser and llm api server - users can query data through complex natural language.
- Support fuzzy query dimension and metric name - users can set the 'metric.dimension.threshold'
parameter to control the fuzzy threshold.
- Support query filter and domain filter in query and search - users can specify domainId and query
filter to filter the results in search and query.
- Support standalone mode - users can integrate semantic and chat services in one process for easy
management and debugging.
- Support dsl query in semantic - users can specify DSL language to query data in Semantic. In the
past, data querying was limited to struct language.
- Add unit and integration testing - add integration tests for single-turn and multi-turn
conversations, to efficiently validate the code.
- Support dimension and metric alias - users can specify one or multiple aliases to expand search
and query.
- Add scheduled semantic metadata update functionality in chat.
- Support create datasource by table name in the web page.
- Add the ability to set permissions for domain.
- Add a local/Remote implementation to the SemanticLayer interface.
### Updated
- Code architecture adjustment in chat.
1) Abstracting into three modules, namely api, core, and knowledge. Providing four core interfaces:
SchemaMapper, SemanticLayer, SemanticParser, and SemanticQuery.
2) Add RuleSemanticQuery and LLMSemanticQuery implement to SemanticQuery.
3) Add all possible queries to the candidate queries, and then select the most suitable query from
the candidate queries.
- Code architecture adjustment in semantic.
1) Refactor semantic layer SQL parsing code through Calcite.
2) Add QueryOptimizer interface.
- Chat config subdivided into detailed and metric scenarios - users can set different parameters in these two scenarios.
### Fixed
- Resolved last word not be recognized in SchemaMapper.
- Fix context inheritance problem.
- Fix the error of querying H2 database by month unit.
- Set faker user to context when authentication disable.
## SuperSonic [0.5.0] - 2023-06-15
### Added
- Add the search and query feature in chat according to rules in an extensible way.
- Add semantic/chat independent service for users.
- Add Modeling Interface - users can visually define and maintain semantic models in the web page.
- Add a unified semantic parsing layer - user can query data by struct language.
# Davinci Changelog
## Davinci [0.3.0] - 2023-06-15
### Added
- add data portal
- add metric trend chart
- add feedback component
- add tab component
- add page setting
### Updated
- modify permission process
- optimize css style
- optimize filter
### Removed
- delete view module

View File

@@ -1,70 +1,63 @@
English | [中文](README_CN.md)
[中文介绍](README_CN.md) | [文档中心](https://github.com/tencentmusic/supersonic/wiki)
# SuperSonic (超音数)
**SuperSonic is an out-of-the-box yet highly extensible framework for building a data chatbot**. SuperSonic provides a chat interface that empowers users to query data using natural language and visualize the results with suitable charts. To enable such experience, the only thing necessary is to define logical semantic models (metrics, dimensions, relationships, etc) on top of physical data models, and no data modification or copying is required. Meanwhile SuperSonic is designed to be plugable, allowing new functionalities to be added through plugins and core components to be integrated into other systems.
**SuperSonic is an out-of-the-box yet highly extensible framework for building ChatBI**. SuperSonic provides a chat interface that empowers users to query data using natural language and visualize the results with suitable charts. To enable such experience, the only thing necessary is to build logical semantic models (definition of metrics/dimensions/entities, along with their meaning, context and relationships) on top of physical data models, and no data modification or copying is required. Meanwhile, SuperSonic is designed to be pluggable, allowing new functionalities to be added through plugins and core components to be integrated with other systems.
<img src="./docs/images/supersonic_demo.gif" align="center"/>
<img src="./docs/images/supersonic_demo.gif" height="100%" width="100%" align="center"/>
## Motivation
The emergence of Large Language Models (LLMs) like ChatGPT is reshaping the way information is retrieved. In the field of data analytics, both academia and industry are primarily focused on leveraging deep learning models to convert natural language queries into SQL queries. While some works show promising results, they are not applicable to real-world scenarios.
The emergence of Large Language Model (LLM) like ChatGPT is reshaping the way information is retrieved. In the field of data analytics, both academia and industry are primarily focused on leveraging LLM to convert natural language into SQL (so called text2sql or nl2sql). While some works exhibit promising results, their **reliability** is inadequate for real-world applications.
From our perspective, the key to filling the real-world gap lies in two aspects:
1. Utilize a combination of rule-based and model-based semantic parsers to deal with different scenarios
2. Introduce a semantic model layer to encapsulate underlying complexity thus simplify the semantic parsers
From our perspective, the key to filling the real-world gap lies in three aspects:
1. Introduce a semantic layer encapsulating underlying data context(joins, formulas, etc) to reduce **complexity**.
2. Augment the LLM with schema mappers(as a kind of preprocessor) and semantic correctors(as a kind of postprocessor) to mitigate **hallucination**.
3. Utilize heuristic rules when necessary to improve **efficiency**(in terms of latency and cost).
With these ideas in mind, we developed SuperSonic as a reference implementation and used it to power our real-world products. Additionally, to encourage further development of data chatbots, we decided to open source SuperSonic as an extensible framework.
With these ideas in mind, we develop SuperSonic as a practical reference implementation and use it to power our real-world products. Additionally, to facilitate further development of ChatBI, we decide to open source SuperSonic as an extensible framework.
## Out-of-the-box Features
- Built-in graphical interface for business users to enter data queries
- Built-in graphical interface for analytics engineers to manage semantic models
- Built-in CUI(Chat User Interface) for *business users* to enter data queries
- Built-in GUI(Graphical User Interface) for *analytics engineers* to build semantic models
- Built-in GUI for *system administrators* to manage chat agents and third-party plugins
- Support input auto-completion as well as query recommendation
- Support multi-turn conversation and history context management
- Support three-level permission control: domain-level, column-level and row-level
- Support four-level permission control: domain-level, model-level, column-level and row-level
## Extensible Components
SuperSonic is composed of two layers: supersonic-chat and supersonic-semantic. The chat layer is responsible for converting **natural language query** into semantic query (also known as DSL query), whereas the semantic layer is responsible for converting DSL query into **SQL query**. The high-level architecture and main process flow is shown in below diagram:
The high-level architecture and main process flow is as follows:
<img src="./docs/images/supersonic_components.png" height="65%" width="65%" align="center"/>
<img src="./docs/images/supersonic_components.png" height="80%" width="80%" align="center"/>
- **Knowledge Base:** extracts schema information periodically from the semantic models and build dictionary and index to facilitate schema mapping.
- **Schema Mapper:** identifies references to schema elements(metrics/dimensions/entities/values) in user queries. It matches the query text against the knowledge base.
### Chat Layer
- **Semantic Parser:** understands user queries and extracts semantic information. It consists of a combination of rule-based and model-based parsers, each of which deals with specific scenarios.
The chat layer contains four core components:
- **Semantic Corrector:** checks validity of extracted semantic information and performs correction and optimization if needed.
- **Chat Interface:** accepts user queries and answer results with appropriate visualization charts. It supports input auto-completion as well as multi-turn conversation.
- **Semantic Interpreter:** performs execution according to extracted semantic information. It generates SQL statements and executes them against physical data models.
- **Schema Mapper Chain:** identifies references to semantic schema elements in user queries. It matches queries against the knowledage base which is constructed using the schema of semantic models.
- **Semantic Parser Chain:** resolves query mode based on mapped semantic models. It is composed of a group of rule-based and model-based parsers, each of which deals with specific scenarios.
- **Semantic Query:** performs execution according to the results of semantic parsing. The default semantic query would submit DSL to the semantic component, but new types of semantic query can be extended.
### Semantic Layer
The semantic layer contains four core components:
- **Modeling Interface:** empowers analytics engineers to visually define and maintain semantic models. The configurations related to access permission and chat conversation can also be set on the UI.
- **DSL Parser:** converts DSL expression to intermediate structures. To make it easily integratable with analytics applications, SQL (without joins and calculation formulas) is used as the DSL.
- **Query Planner:** builds and optimizes query plans according to various rules.
- **SQL Generator:** generates final SQL expression (with joins and calculation formulas) based on the query plan.
- **Chat Plugin:** extends functionality with third-party tools. The LLM is going to select the most suitable one, given all configured plugins with function description and sample questions.
## Quick Demo
SuperSonic comes with sample semantic models as well as chat conversations that can be used as a starting point. Please follow the steps:
- Download the latest prebuilt binary from the [release page](https://github.com/tencentmusic/supersonic/releases)
- Run script "bin/start-standalone.sh" to start a standalone server
- Visit http://localhost:9080 in browser to start exploration
- Run script "bin/supersonic-daemon.sh" to start services (one java process and one python process)
- Visit http://localhost:9080 in the browser to start exploration
## How to Build
## Build and Development
Pull the source code and run script "assembly/bin/build-standalone.sh" to build packages in the standalone mode.
Please refer to project [wiki](https://github.com/tencentmusic/supersonic/wiki).
## WeChat Contact
Please follow SuperSonic wechat official account:
<img src="./docs/images/supersonic_wechat_oa.png" height="50%" width="50%" align="center"/>

View File

@@ -1,65 +1,61 @@
# 超音数SuperSonic
**超音数是一个开箱即用且易于扩展的数据问答对话框架**。通过超音数的问答对话界面,用户能够使用自然语言查询数据,系统会选择合适的可视化图表呈现结果。超音数不需要修改或复制数据,只需要在物理数据之上构建逻辑语义模型(定义指标维度、相互间关系等),即可开启数据问答体验。与此同时,超音数被设计为可插拔式框架,允许以插件形式来扩展新功能,或者将核心组件与其他系统集成。
**超音数是一个开箱即用且易于扩展的数据问答对话框架**。通过超音数的问答对话界面,用户能够使用自然语言查询数据,系统会选择合适的可视化图表呈现结果。超音数不需要修改或复制数据,只需要在物理数据模型之上构建逻辑语义模型(指标/维度/实体的定义,以及他们的业务含义、相互间关系等),即可开启数据问答体验。与此同时,超音数被设计为可插拔式框架,允许以插件形式来扩展新功能,或者将核心组件与其他系统集成。
<img src="./docs/images/supersonic_demo.gif" align="center"/>
<img src="./docs/images/supersonic_demo.gif" height="100%" width="100%" align="center"/>
## 项目动机
大型语言模型LLMs如ChatGPT的出现正在重塑信息检索的方式。在数据分析领域学术界和工业界主要关注利用深度学习模型将自然语言查询转换为SQL查询。虽然一些工作显示出有前景的结果但它们还并不适用于实际场景
大型语言模型LLMs如ChatGPT的出现正在重塑信息检索的方式。在数据分析领域学术界和工业界主要关注利用深度学习模型将自然语言查询转换为SQL查询。虽然一些工作显示出有前景的结果但它们的可靠性还达不到生产可用的要求
在我们看来,为了在实际场景发挥价值,有个关键点:
1. 将基于规则和基于模型的语义解析器相结合,发挥各自优势,以便处理不同的场景
2. 引入语义模型层来封装数据底层的复杂性,从而简化语义解析器的问题求解空间
在我们看来,为了在实际场景发挥价值,有个关键点:
1. 引入语义模型层封装底层数据的上下文关联、公式等降低SQL生成的**复杂度**。
2. 通过一前一后的模式映射器和语义修正器来缓解LLM常见的**幻觉**现象。
3. 设计启发式的规则,在一些特定场景提升语义解析的**效率**。
为了验证上述想法,我们开发了超音数项目,并将其应用在实际的内部产品中。与此同时,我们决定将超音数作为一个可扩展的框架开源,希望能够促进数据问答对话领域的进一步发展。
为了验证上述想法,我们开发了超音数项目,并将其应用在实际的内部产品中。与此同时,我们将超音数作为一个可扩展的框架开源,希望能够促进数据问答对话领域的进一步发展。
## 开箱即用的特性
- 内置图形界面以便业务用户输入数据查询
- 内置图形界面以便分析工程师管理语义模型
- 支持文本输入的联想和查询问题的推荐
- 支持多轮对话,根据语境自动切换上下文
- 支持三级权限控制:主题域级、列级、行级
- 内置对话界面以便*业务用户*输入数据查询
- 内置图形界面以便*分析工程师*构建语义模型
- 内置图形界面以便*系统管理员*管理第三方插件和对话助理。
- 支持文本输入的联想和查询问题的推荐。
- 支持多轮对话,根据语境自动切换上下文。
- 支持四级权限控制:主题域级、模型级、列级、行级。
## 易于扩展的组件
超音数主要分为两层supersonic-chat and supersonic-semantic。问答层负责将自然语言查询转换为语义查询也称为DSL查询而语义层负责将DSL查询转换为SQL查询。超音数的整体架构和主流程如下图所示:
超音数的整体架构和主流程如下图所示:
<img src="./docs/images/supersonic_components.png" height="80%" width="80%" align="center"/>
<img src="./docs/images/supersonic_components.png" height="65%" width="65%" align="center"/>
### 问答层
- **模型知识库(Knowledge Base)** 定期从语义模型中提取相关的模式信息,构建词典和索引,以便后续的模式映射。
问答层包含以下4个核心组件
- **模式映射器(Schema Mapper)** 将自然语言文本在知识库中进行匹配,为后续的语义解析提供相关信息。
- **问答对话界面(chat interface)**:接受用户查询并选择合适的可视化图表呈现结果,支持输入联想和多轮对话
- **语义解析器(Semantic Parser)** 理解用户查询并抽取语义信息,其由一组基于规则和基于模型的解析器组成,每个解析器可应对不同的特定场景
- **模式映射器(schema mapper)**基于语义模型的schema构建知识库然后将自然语言查询在知识库中进行匹配为后续的语义解析提供相关信息
- **语义修正器(Semantic Corrector)** 检查语义信息的合法性,对不合法的信息做修正和优化处理
- **语义解析器链(semantic parser chain)**:识别查询模式并选择最匹配的语义模型,其由一组基于规则或模型的解析器组成,每个解析器可用于应对不同的特定场景
- **语义解释器(Semantic Interpreter)** 根据语义信息生成物理SQL执行查询
- **语义查询(semantic query)**: 根据语义解析的结果执行查询默认的语义查询会将DSL提交给语义组件但可以扩展新类型的查询。
### 语义层
语义层包含以下4个核心组件
- **语义建模界面(modeling interface)**:使分析工程师能够通过可视化方式定义和维护语义模型,与访问权限和聊天对话相关的配置也可以在用户界面上设置。
- **DSL解析器(DSL parser)**将DSL表达式转换为中间结构。为了使其易于与分析应用程序集成使用SQL不含join和计算公式来作为DSL。
- **查询计划器(query planner)**:根据各种规则来构建和优化查询计划。
- **SQL生成器(SQL genenrator)**基于查询计划来生成最终的SQL语句含join和计算公式
- **问答插件(Chat Plugin)** 通过第三方工具扩展功能。给定所有配置的插件及其功能描述和示例问题,大语言模型将选择最合适的插件。
## 快速体验
超音数自带样例的语义模型和问答对话,只需以下三步即可快速体验:
- 从[release page](https://github.com/tencentmusic/supersonic/releases)下载预先构建好的发行包
- 运行 "bin/start-standalone.sh"启动服务
- 运行 "bin/supersonic-daemon.sh"启动服务一个Java进程和一个Python进程
- 在浏览器访问http://localhost:9080 开启探索
## 如何构建
## 如何构建和部署
下载源码包,运行脚本"assembly/bin/build-standalone.sh",将所有服务一起编译打包
请参考项目[wiki](https://github.com/tencentmusic/supersonic/wiki)。
## 微信联系方式
欢迎关注微信公众号:
<img src="./docs/images/supersonic_wechat_oa.png" height="50%" width="50%" align="center"/>

View File

@@ -1,12 +0,0 @@
#!/usr/bin/env bash
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $sbinDir/../)
runtimeDir=$baseDir/runtime
buildDir=$baseDir/build
cd $baseDir
#1. move package to build
cp $baseDir/../launchers/chat/target/*.tar.gz ${buildDir}/supersonic-chat.tar.gz

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env bash
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $sbinDir/../)
runtimeDir=$baseDir/runtime
buildDir=$baseDir/build
cd $baseDir
#1. build semantic service
rm -fr ${buildDir}/*.tar.gz
rm -fr dist
mvn -f $baseDir/../ clean package -DskipTests
#2. move package to build
cp $baseDir/../launchers/semantic/target/*.tar.gz ${buildDir}/supersonic-semantic.tar.gz
#3. build webapp
chmod +x $baseDir/../webapp/start-fe-prod.sh
cd ../webapp
sh ./start-fe-prod.sh
cp -fr ./supersonic-webapp.tar.gz ${buildDir}/

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env bash
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $sbinDir/../)
runtimeDir=$baseDir/runtime
buildDir=$baseDir/build
cd $baseDir
#1. build semantic chat service
rm -fr ${buildDir}/*.tar.gz
rm -fr dist
mvn -f $baseDir/../ clean package -DskipTests
#2. move package to build
cp $baseDir/../launchers/standalone/target/*.tar.gz ${buildDir}/supersonic.tar.gz
#3. build webapp
chmod +x $baseDir/../webapp/start-fe-prod.sh
cd ../webapp
sh ./start-fe-prod.sh
cp -fr ./supersonic-webapp.tar.gz ${buildDir}/

View File

@@ -1,35 +0,0 @@
#!/usr/bin/env bash
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $sbinDir/../)
runtimeDir=$baseDir/../runtime
buildDir=$baseDir/build
cd $baseDir
#2. package lib
tar -zxvf ${buildDir}/supersonic-chat.tar.gz -C ${runtimeDir}
mv ${runtimeDir}/launchers-chat-* ${runtimeDir}/supersonic-chat
tar -zxvf ${buildDir}/supersonic-webapp.tar.gz -C ${buildDir}
mkdir -p ${runtimeDir}/supersonic-chat/webapp
cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-chat/webapp
rm -fr ${buildDir}/supersonic-webapp
json=$(cat ${runtimeDir}/supersonic-chat/webapp/supersonic.config.json)
json=$(echo $json | jq '.env="chat"')
echo $json > ${runtimeDir}/supersonic-chat/webapp/supersonic.config.json
#3. start service
#3.1 start chat service
echo ${runtimeDir}
sh ${runtimeDir}/supersonic-chat/bin/service.sh restart
#3.2 start llm service
sh ${runtimeDir}/supersonic-chat/llm/bin/service.sh restart

View File

@@ -1,36 +0,0 @@
#!/usr/bin/env bash
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $sbinDir/../)
runtimeDir=$baseDir/../runtime
buildDir=$baseDir/build
cd $baseDir
#1. clear file
mkdir -p ${runtimeDir}
rm -fr ${runtimeDir}/*
#2. package lib
tar -zxvf ${buildDir}/supersonic-semantic.tar.gz -C ${runtimeDir}
mv ${runtimeDir}/launchers-semantic-* ${runtimeDir}/supersonic-semantic
tar -zxvf ${buildDir}/supersonic-webapp.tar.gz -C ${buildDir}
mkdir -p ${runtimeDir}/supersonic-semantic/webapp
cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-semantic/webapp
rm -fr ${buildDir}/supersonic-webapp
json=$(cat ${runtimeDir}/supersonic-semantic/webapp/supersonic.config.json)
json=$(echo $json | jq '.env="semantic"')
echo $json > ${runtimeDir}/supersonic-semantic/webapp/supersonic.config.json
#3. start service
sh ${runtimeDir}/supersonic-semantic/bin/service.sh restart

View File

@@ -1,32 +0,0 @@
#!/usr/bin/env bash
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $sbinDir/../)
runtimeDir=$baseDir/../runtime
buildDir=$baseDir/build
cd $baseDir
#1. clear file
mkdir -p ${runtimeDir}
rm -fr ${runtimeDir}/*
#2. package lib
tar -zxvf ${buildDir}/supersonic.tar.gz -C ${runtimeDir}
mv ${runtimeDir}/launchers-standalone-* ${runtimeDir}/supersonic-standalone
tar -zxvf ${buildDir}/supersonic-webapp.tar.gz -C ${buildDir}
mkdir -p ${runtimeDir}/supersonic-standalone/webapp
cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-standalone/webapp
rm -fr ${buildDir}/supersonic-webapp
#3. start service
#start standalone service
sh ${runtimeDir}/supersonic-standalone/bin/service.sh restart
#start llm service
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh restart

View File

@@ -0,0 +1,53 @@
@echo off
setlocal
chcp 65001
set "sbinDir=%~dp0"
set "baseDir=%~dp0.."
set "buildDir=%baseDir%\build"
set "runtimeDir=%baseDir%\..\runtime"
set "pip_path=pip3"
rem 1. build backend java modules
del /q "%buildDir%\*.tar.gz" 2>NUL
call mvn -f "%baseDir%\..\pom.xml" clean package -DskipTests
rem 2. move package to build
echo f|xcopy "%baseDir%\..\launchers\standalone\target\*.tar.gz" "%buildDir%\supersonic-standalone.tar.gz"
rem 3. build frontend webapp
cd "%baseDir%\..\webapp"
call start-fe-prod.bat
copy /y "%baseDir%\..\webapp\supersonic-webapp.tar.gz" "%buildDir%\"
rem 4. copy webapp to java classpath
cd "%buildDir%"
tar -zxvf supersonic-webapp.tar.gz
move supersonic-webapp webapp
move webapp ..\..\launchers\standalone\target\classes
rem 5. build backend python modules
echo "start installing python modules with pip: ${pip_path}"
set requirementPath="%baseDir%/../chat/core/src/main/python/requirements.txt"
%pip_path% install -r %requirementPath%
echo "install python modules success"
call :BUILD_RUNTIME
:BUILD_RUNTIME
rem 6. reset runtime
rd /s /q "%runtimeDir%"
mkdir "%runtimeDir%"
tar -zxvf "%buildDir%\supersonic-standalone.tar.gz" -C "%runtimeDir%"
for /d %%f in ("%runtimeDir%\launchers-standalone-*") do (
move "%%f" "%runtimeDir%\supersonic-standalone"
)
rem 7. copy webapp to runtime
tar -zxvf "%buildDir%\supersonic-webapp.tar.gz" -C "%buildDir%"
if not exist "%runtimeDir%\supersonic-standalone\webapp" mkdir "%runtimeDir%\supersonic-standalone\webapp"
xcopy /s /e /h /y "%buildDir%\supersonic-webapp\*" "%runtimeDir%\supersonic-standalone\webapp"
if not exist "%runtimeDir%\supersonic-standalone\conf\webapp" mkdir "%runtimeDir%\supersonic-standalone\conf\webapp"
xcopy /s /e /h /y "%runtimeDir%\supersonic-standalone\webapp\*" "%runtimeDir%\supersonic-standalone\conf\webapp"
rd /s /q "%buildDir%\supersonic-webapp"
endlocal

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
set -x
sbinDir=$(cd "$(dirname "$0")"; pwd)
chmod +x $sbinDir/supersonic-common.sh
source $sbinDir/supersonic-common.sh
cd $baseDir
#1. build backend java modules
rm -fr ${buildDir}/*.tar.gz
rm -fr dist
set +x
mvn -f $baseDir/../ clean package -DskipTests
#2. move package to build
cp $baseDir/../launchers/semantic/target/*.tar.gz ${buildDir}/supersonic-semantic.tar.gz
cp $baseDir/../launchers/chat/target/*.tar.gz ${buildDir}/supersonic-chat.tar.gz
cp $baseDir/../launchers/standalone/target/*.tar.gz ${buildDir}/supersonic-standalone.tar.gz
#3. build frontend webapp
chmod +x $baseDir/../webapp/start-fe-prod.sh
cd ../webapp
sh ./start-fe-prod.sh
cp -fr ./supersonic-webapp.tar.gz ${buildDir}/
#4. copy webapp to java classpath
cd $buildDir
tar xvf supersonic-webapp.tar.gz
mv supersonic-webapp webapp
cp -fr webapp ../../launchers/semantic/target/classes
cp -fr webapp ../../launchers/chat/target/classes
cp -fr webapp ../../launchers/standalone/target/classes
rm -fr ${buildDir}/webapp
#5. build backend python modules
echo "start installing python modules with pip: ${pip_path}"
requirementPath=$baseDir/../chat/core/src/main/python/requirements.txt
${pip_path} install -r ${requirementPath}
echo "install python modules success"
#6. reset runtime
rm -fr $runtimeDir/*
moveAllToRuntime
setEnvToWeb chat
setEnvToWeb semantic

105
assembly/bin/supersonic-common.sh Executable file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env bash
# environment parameters
python_path=${PYTHON_PATH:-"python3"}
pip_path=${PIP_PATH:-"pip3"}
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(cd "$sbinDir/.." && pwd -P)
runtimeDir=$baseDir/../runtime
buildDir=$baseDir/build
readonly CHAT_APP_NAME="supersonic_chat"
readonly SEMANTIC_APP_NAME="supersonic_semantic"
readonly LLMPARSER_APP_NAME="supersonic_llmparser"
readonly STANDALONE_APP_NAME="supersonic_standalone"
readonly CHAT_SERVICE="chat"
readonly SEMANTIC_SERVICE="semantic"
readonly LLMPARSER_SERVICE="llmparser"
readonly STANDALONE_SERVICE="standalone"
readonly LLMPARSER_HOST="127.0.0.1"
readonly LLMPARSER_PORT="9092"
function setEnvToWeb {
model_name=$1
json='{"env": "'$model_name'"}'
echo $json > ${runtimeDir}/supersonic-${model_name}/webapp/supersonic.config.json
echo $json > $baseDir/../launchers/${model_name}/target/classes/webapp/supersonic.config.json
}
function moveToRuntime {
model_name=$1
tar -zxvf ${buildDir}/supersonic-${model_name}.tar.gz -C ${runtimeDir}
mv ${runtimeDir}/launchers-${model_name}-* ${runtimeDir}/supersonic-${model_name}
mkdir -p ${runtimeDir}/supersonic-${model_name}/webapp
cp -fr ${buildDir}/webapp/* ${runtimeDir}/supersonic-${model_name}/webapp
}
function moveAllToRuntime {
mkdir -p ${runtimeDir}
tar xvf ${buildDir}/supersonic-webapp.tar.gz -C ${buildDir}
mv ${buildDir}/supersonic-webapp ${buildDir}/webapp
moveToRuntime chat
moveToRuntime semantic
moveToRuntime standalone
rm -fr ${buildDir}/webapp
}
# run java service
function runJavaService {
javaRunDir=${runtimeDir}/supersonic-${model_name}
local_app_name=$1
libDir=$javaRunDir/lib
confDir=$javaRunDir/conf
CLASSPATH=""
CLASSPATH=$CLASSPATH:$confDir
for jarPath in $libDir/*.jar; do
CLASSPATH=$CLASSPATH:$jarPath
done
export CLASSPATH
export LANG="zh_CN.UTF-8"
cd $javaRunDir
if [[ "$JAVA_HOME" == "" ]]; then
JAVA_HOME=$(ls /usr/jdk64/jdk* -d 2>/dev/null | xargs | awk '{print "'$local_app_name'"}')
fi
export PATH=$JAVA_HOME/bin:$PATH
command="-Dfile.encoding="UTF-8" -Duser.language="Zh" -Duser.region="CN" -Duser.timezone="GMT+08" -Dapp_name=${local_app_name} -Xms1024m -Xmx2048m "$main_class
mkdir -p $javaRunDir/logs
if [[ "$is_test" == "true" ]]; then
java -Dspring.profiles.active="dev" $command >/dev/null 2>$javaRunDir/logs/error.log &
else
java $command $javaRunDir >/dev/null 2>$javaRunDir/logs/error.log &
fi
}
# run python service
function runPythonService {
pythonRunDir=${runtimeDir}/supersonic-${model_name}/llmparser
cd $pythonRunDir
nohup ${python_path} supersonic_llmparser.py > $pythonRunDir/llmparser.log 2>&1 &
# add health check
for i in {1..10}
do
echo "llmparser health check attempt $i..."
response=$(curl -s http://${LLMPARSER_HOST}:${LLMPARSER_PORT}/health)
echo "llmparser health check response: $response"
status_ok="Healthy"
if [[ $response == *$status_ok* ]] ; then
echo "llmparser Health check passed."
break
else
if [ "$i" -eq 10 ]; then
echo "llmparser Health check failed after 10 attempts. Exiting."
fi
echo "Retrying after 5 seconds..."
sleep 5
fi
done
}

View File

@@ -0,0 +1,118 @@
@echo off
setlocal
chcp 65001
set "sbinDir=%~dp0"
set "baseDir=%~dp0.."
set "runtimeDir=%baseDir%\..\runtime"
set "buildDir=%baseDir%\build"
set "main_class=com.tencent.supersonic.StandaloneLauncher"
set "python_path=python"
set "pip_path=pip3"
set "standalone_service=standalone"
set "llmparser_service=llmparser"
set "javaRunDir=%runtimeDir%\supersonic-standalone"
set "pythonRunDir=%runtimeDir%\supersonic-standalone\llmparser"
set "command=%~1"
set "service=%~2"
if "%service%"=="" (
set "service=%standalone_service%"
)
call :BUILD_RUNTIME
if "%command%"=="restart" (
call :STOP
call :START
goto :EOF
) else if "%command%"=="start" (
call :START
goto :EOF
) else if "%command%"=="stop" (
call :STOP
goto :EOF
) else if "%command%"=="reload" (
call :RELOAD_EXAMPLE
goto :EOF
) else (
echo "Use command {start|stop|restart} to run."
goto :EOF
)
:START
if "%service%"=="%llmparser_service%" (
call :START_PYTHON
goto :EOF
)
call :START_PYTHON
call :START_JAVA
goto :EOF
:STOP
if "%service%"=="%llmparser_service%" (
call :STOP_PYTHON
goto :EOF
)
call :STOP_PYTHON
call :STOP_JAVA
goto :EOF
:START_PYTHON
echo 'python service starting, see logs in llmparser/llmparser.log'
cd "%pythonRunDir%"
start /B %python_path% supersonic_llmparser.py > %pythonRunDir%\llmparser.log 2>&1
timeout /t 10 >nul
echo 'python service started'
goto :EOF
:START_JAVA
echo 'java service starting, see logs in logs/'
cd "%javaRunDir%"
if not exist "%runtimeDir%\supersonic-standalone\logs" mkdir "%runtimeDir%\supersonic-standalone\logs"
set "libDir=%runtimeDir%\supersonic-%service%\lib"
set "confDir=%runtimeDir%\supersonic-%service%\conf"
set "webDir=%runtimeDir%\supersonic-%service%\webapp"
set "classpath=%confDir%;%webDir%;%libDir%\*"
set "java-command=-Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 -Xms1024m -Xmx2048m -cp %CLASSPATH% %MAIN_CLASS%"
start /B java %java-command% >nul 2>&1
timeout /t 10 >nul
echo 'java service started'
goto :EOF
:STOP_PYTHON
for /f "tokens=2" %%i in ('tasklist ^| findstr /i "python"') do (
taskkill /PID %%i /F
echo "python service (PID = %%i) is killed."
)
goto :EOF
:STOP_JAVA
for /f "tokens=2" %%i in ('tasklist ^| findstr /i "java"') do (
taskkill /PID %%i /F
echo "java service (PID = %%i) is killed."
)
goto :EOF
:RELOAD_EXAMPLE
cd "%runtimeDir%\supersonic-standalone\llmparser\sql"
start %python_path% examples_reload_run.py
goto :EOF
:BUILD_RUNTIME
rem 6. reset runtime
if exist "%runtimeDir%" goto :EOF
mkdir "%runtimeDir%"
tar -zxvf "%buildDir%\supersonic-standalone.tar.gz" -C "%runtimeDir%"
for /d %%f in ("%runtimeDir%\launchers-standalone-*") do (
move "%%f" "%runtimeDir%\supersonic-standalone"
)
rem 7. copy webapp to runtime
tar -zxvf "%buildDir%\supersonic-webapp.tar.gz" -C "%buildDir%"
if not exist "%runtimeDir%\supersonic-standalone\webapp" mkdir "%runtimeDir%\supersonic-standalone\webapp"
xcopy /s /e /h /y "%buildDir%\supersonic-webapp\*" "%runtimeDir%\supersonic-standalone\webapp"
if not exist "%runtimeDir%\supersonic-standalone\conf\webapp" mkdir "%runtimeDir%\supersonic-standalone\conf\webapp"
xcopy /s /e /h /y "%runtimeDir%\supersonic-standalone\webapp\*" "%runtimeDir%\supersonic-standalone\conf\webapp"
rd /s /q "%buildDir%\supersonic-webapp"

147
assembly/bin/supersonic-daemon.sh Executable file
View File

@@ -0,0 +1,147 @@
#!/usr/bin/env bash
set -x
sbinDir=$(cd "$(dirname "$0")"; pwd)
chmod +x $sbinDir/supersonic-common.sh
source $sbinDir/supersonic-common.sh
# 1.init environment parameters
if [ ! -d "$runtimeDir" ]; then
echo "the runtime dir does not exist move all to runtime"
moveAllToRuntime
fi
set +x
command=$1
service=$2
if [ -z "$service" ]; then
service=${STANDALONE_SERVICE}
fi
app_name=$STANDALONE_APP_NAME
main_class="com.tencent.supersonic.StandaloneLauncher"
model_name=$service
if [ "$service" == "llmparser" ]; then
model_name=${STANDALONE_SERVICE}
fi
cd $baseDir
# 2.set main class
function setMainClass {
if [ "$service" == $CHAT_SERVICE ]; then
main_class="com.tencent.supersonic.ChatLauncher"
elif [ "$service" == $SEMANTIC_SERVICE ]; then
main_class="com.tencent.supersonic.SemanticLauncher"
fi
}
setMainClass
# 3.set app name
function setAppName {
if [ "$service" == $CHAT_SERVICE ]; then
app_name=$CHAT_APP_NAME
elif [ "$service" == $SEMANTIC_SERVICE ]; then
app_name=$SEMANTIC_APP_NAME
elif [ "$service" == $LLMPARSER_SERVICE ]; then
app_name=$LLMPARSER_APP_NAME
fi
}
setAppName
function reloadExamples {
pythonRunDir=${runtimeDir}/supersonic-${model_name}/llmparser
cd $pythonRunDir/sql
${python_path} examples_reload_run.py
}
function start()
{
local_app_name=$1
pid=$(ps aux |grep ${local_app_name} | grep -v grep | awk '{print $2}')
if [[ "$pid" == "" ]]; then
if [[ ${local_app_name} == $LLMPARSER_APP_NAME ]]; then
runPythonService ${local_app_name}
else
runJavaService ${local_app_name}
fi
else
echo "Process (PID = $pid) is running."
return 1
fi
}
function stop()
{
pid=$(ps aux | grep $1 | grep -v grep | awk '{print $2}')
if [[ "$pid" == "" ]]; then
echo "Process $1 is not running !"
return 1
else
kill -9 $pid
echo "Process (PID = $pid) is killed !"
return 0
fi
}
function reload()
{
if [[ $1 == $LLMPARSER_APP_NAME ]]; then
reloadExamples
fi
}
# 4. execute command operation
case "$command" in
start)
if [ "$service" == $STANDALONE_SERVICE ]; then
echo "Starting $LLMPARSER_APP_NAME"
start $LLMPARSER_APP_NAME
echo "Starting $app_name"
start $app_name
else
echo "Starting $app_name"
start $app_name
fi
echo "Start success"
;;
stop)
if [ "$service" == $STANDALONE_SERVICE ]; then
echo "Stopping $LLMPARSER_APP_NAME"
stop $LLMPARSER_APP_NAME
echo "Stopping $app_name"
stop $app_name
else
echo "Stopping $app_name"
stop ${app_name}
fi
echo "Stop success"
;;
reload)
echo "Reloading ${app_name}"
reload ${app_name}
echo "Reload success"
;;
restart)
if [ "$service" == $STANDALONE_SERVICE ]; then
echo "Stopping ${app_name}"
stop ${app_name}
echo "Stopping ${LLMPARSER_APP_NAME}"
stop $LLMPARSER_APP_NAME
echo "Starting ${LLMPARSER_APP_NAME}"
start $LLMPARSER_APP_NAME
echo "Starting ${app_name}"
start ${app_name}
else
echo "Stopping ${app_name}"
stop ${app_name}
echo "Starting ${app_name}"
start ${app_name}
fi
echo "Restart success"
;;
*)
echo "Use command {start|stop|restart} to run."
exit 1
esac

View File

@@ -6,14 +6,6 @@
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0777</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/main/resources</directory>
<outputDirectory>conf</outputDirectory>
@@ -30,7 +22,7 @@
</fileSet>
<fileSet>
<directory>${project.basedir}/../../chat/core/src/main/python</directory>
<outputDirectory>llm</outputDirectory>
<outputDirectory>llmparser</outputDirectory>
<fileMode>0777</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>

View File

@@ -0,0 +1,25 @@
package com.tencent.supersonic.auth.api.authentication.adaptor;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import java.util.List;
import java.util.Set;
public interface UserAdaptor {
List<String> getUserNames();
List<User> getUserList();
List<Organization> getOrganizationTree();
void register(UserReq userReq);
String login(UserReq userReq);
List<User> getUserByOrg(String key);
Set<String> getUserAllOrgId(String userName);
}

View File

@@ -9,18 +9,19 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class AuthenticationConfig {
@Value("${authentication.exclude.path:XXX}")
private String excludePath;
@Value("${authentication.include.path:/api}")
private String includePath;
@Value("${authentication.enable:false}")
private boolean enabled;
@Value("${authentication.token.secret:secret}")
private String tokenSecret;
@Value("${authentication.token.http.header.key:Auth}")
@Value("${authentication.token.http.header.key:Authorization}")
private String tokenHttpHeaderKey;
}

View File

@@ -12,6 +12,8 @@ public class UserConstants {
public static final String TOKEN_USER_EMAIL = "token_user_email";
public static final String TOKEN_IS_ADMIN = "token_is_admin";
public static final String TOKEN_ALGORITHM = "HS512";
public static final String TOKEN_CREATE_TIME = "token_create_time";

View File

@@ -0,0 +1,23 @@
package com.tencent.supersonic.auth.api.authentication.pojo;
import com.google.common.collect.Lists;
import lombok.Data;
import java.util.List;
@Data
public class Organization {
private String id;
private String parentId;
private String name;
private String fullName;
private List<Organization> subOrganizations = Lists.newArrayList();
private boolean isRoot;
}

View File

@@ -18,17 +18,22 @@ public class User {
private String email;
public static User get(Long id, String name, String displayName, String email) {
return new User(id, name, displayName, email);
private Integer isAdmin;
public static User get(Long id, String name, String displayName, String email, Integer isAdmin) {
return new User(id, name, displayName, email, isAdmin);
}
public static User getFakeUser() {
return new User(1L, "admin", "admin", "admin@email");
return new User(1L, "admin", "admin", "admin@email", 1);
}
public String getDisplayName() {
return StringUtils.isBlank(displayName) ? name : displayName;
}
public boolean isSuperAdmin() {
return isAdmin != null && isAdmin == 1;
}
}

View File

@@ -9,13 +9,14 @@ public class UserWithPassword extends User {
private String password;
public UserWithPassword(Long id, String name, String displayName, String email, String password) {
super(id, name, displayName, email);
public UserWithPassword(Long id, String name, String displayName, String email, String password, Integer isAdmin) {
super(id, name, displayName, email, isAdmin);
this.password = password;
}
public static UserWithPassword get(Long id, String name, String displayName, String email, String password) {
return new UserWithPassword(id, name, displayName, email, password);
public static UserWithPassword get(Long id, String name, String displayName,
String email, String password, Integer isAdmin) {
return new UserWithPassword(id, name, displayName, email, password, isAdmin);
}
}

View File

@@ -1,9 +1,11 @@
package com.tencent.supersonic.auth.api.authentication.service;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import java.util.List;
import java.util.Set;
public interface UserService {
@@ -14,4 +16,10 @@ public interface UserService {
void register(UserReq userCmd);
String login(UserReq userCmd);
Set<String> getUserAllOrgId(String userName);
List<User> getUserByOrg(String key);
List<Organization> getOrganizationTree();
}

View File

@@ -6,7 +6,7 @@ import lombok.Data;
@Data
public class AuthGroup {
private String domainId;
private String modelId;
private String name;
private Integer groupId;
private List<AuthRule> authRules;

View File

@@ -7,14 +7,14 @@ import lombok.ToString;
@ToString
public class AuthRes {
private String domainId;
private String modelId;
private String name;
public AuthRes() {
}
public AuthRes(String domainId, String name) {
this.domainId = domainId;
public AuthRes(String modelId, String name) {
this.modelId = modelId;
this.name = name;
}
}

View File

@@ -11,11 +11,9 @@ import lombok.ToString;
@ToString
public class QueryAuthResReq {
private String user;
private List<String> departmentIds = new ArrayList<>();
private List<AuthRes> resources;
private String domainId;
private String modelId;
}

View File

@@ -1,7 +1,7 @@
package com.tencent.supersonic.auth.api.authorization.request;
import com.tencent.supersonic.common.request.PageBaseReq;
import com.tencent.supersonic.common.pojo.PageBaseReq;
import java.util.List;
import lombok.Data;

View File

@@ -1,18 +1,18 @@
package com.tencent.supersonic.auth.api.authorization.service;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthGroup;
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
public interface AuthService {
List<AuthGroup> queryAuthGroups(String domainId, Integer groupId);
void updateAuthGroup(AuthGroup group);
void addOrUpdateAuthGroup(AuthGroup group);
void removeAuthGroup(AuthGroup group);
AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, HttpServletRequest request);
AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, User user);
}

View File

@@ -1,67 +1,58 @@
package com.tencent.supersonic.auth.authentication.application;
package com.tencent.supersonic.auth.authentication.adaptor;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.tencent.supersonic.auth.api.authentication.adaptor.UserAdaptor;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.domain.repository.UserRepository;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
import java.util.List;
import java.util.stream.Collectors;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.persistence.repository.UserRepository;
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
import com.tencent.supersonic.common.util.ContextUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
private UserTokenUtils userTokenUtils;
public UserServiceImpl(UserRepository userRepository, UserTokenUtils userTokenUtils) {
this.userRepository = userRepository;
this.userTokenUtils = userTokenUtils;
}
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class DefaultUserAdaptor implements UserAdaptor {
private List<UserDO> getUserDOList() {
UserRepository userRepository = ContextUtils.getBean(UserRepository.class);
return userRepository.getUserList();
}
private UserDO getUser(String name) {
UserRepository userRepository = ContextUtils.getBean(UserRepository.class);
return userRepository.getUser(name);
}
public boolean checkExist(UserWithPassword user) {
UserDO userDO = getUser(user.getName());
if (userDO == null) {
return false;
}
return userDO.getPassword().equals(user.getPassword());
}
@Override
public List<String> getUserNames() {
return getUserDOList().stream().map(UserDO::getName).collect(Collectors.toList());
}
@Override
public List<User> getUserList() {
List<UserDO> userDOS = getUserDOList();
return userDOS.stream().map(this::convert).collect(Collectors.toList());
}
@Override
public List<Organization> getOrganizationTree() {
return Lists.newArrayList();
}
private User convert(UserDO userDO) {
User user = new User();
BeanUtils.copyProperties(userDO, user);
return user;
}
@Override
public void register(UserReq userReq) {
UserRepository userRepository = ContextUtils.getBean(UserRepository.class);
List<String> userDOS = getUserNames();
if (userDOS.contains(userReq.getName())) {
throw new RuntimeException(String.format("user %s exist", userReq.getName()));
@@ -73,17 +64,27 @@ public class UserServiceImpl implements UserService {
@Override
public String login(UserReq userReq) {
UserTokenUtils userTokenUtils = ContextUtils.getBean(UserTokenUtils.class);
UserDO userDO = getUser(userReq.getName());
if (userDO == null) {
throw new RuntimeException("user not exist,please register");
}
if (userDO.getPassword().equals(userReq.getPassword())) {
UserWithPassword user = UserWithPassword.get(userDO.getId(), userDO.getName(), userDO.getDisplayName(),
userDO.getEmail(), userDO.getPassword());
userDO.getEmail(), userDO.getPassword(), userDO.getIsAdmin());
return userTokenUtils.generateToken(user);
}
throw new RuntimeException("password not correct, please try again");
}
@Override
public List<User> getUserByOrg(String key) {
return Lists.newArrayList();
}
@Override
public Set<String> getUserAllOrgId(String userName) {
return Sets.newHashSet();
}
}

View File

@@ -1,51 +0,0 @@
package com.tencent.supersonic.auth.authentication.infrastructure.mapper;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDOExample;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserDOMapper {
/**
* @mbg.generated
*/
long countByExample(UserDOExample example);
/**
* @mbg.generated
*/
int deleteByPrimaryKey(Long id);
/**
* @mbg.generated
*/
int insert(UserDO record);
/**
* @mbg.generated
*/
int insertSelective(UserDO record);
/**
* @mbg.generated
*/
List<UserDO> selectByExample(UserDOExample example);
/**
* @mbg.generated
*/
UserDO selectByPrimaryKey(Long id);
/**
* @mbg.generated
*/
int updateByPrimaryKeySelective(UserDO record);
/**
* @mbg.generated
*/
int updateByPrimaryKey(UserDO record);
}

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.auth.authentication.domain.interceptor;
package com.tencent.supersonic.auth.authentication.interceptor;
import java.lang.annotation.ElementType;

View File

@@ -1,10 +1,10 @@
package com.tencent.supersonic.auth.authentication.domain.interceptor;
package com.tencent.supersonic.auth.authentication.interceptor;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.constant.UserConstants;
import com.tencent.supersonic.auth.authentication.application.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
import com.tencent.supersonic.common.util.context.S2ThreadContext;
import com.tencent.supersonic.auth.authentication.service.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
import com.tencent.supersonic.common.util.S2ThreadContext;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
@@ -42,6 +42,17 @@ public abstract class AuthenticationInterceptor implements HandlerInterceptor {
return excludePaths.stream().anyMatch(uri::startsWith);
}
protected boolean isIncludedUri(String uri) {
String includePathStr = authenticationConfig.getIncludePath();
if (Strings.isEmpty(includePathStr)) {
return false;
}
List<String> includePaths = Arrays.asList(includePathStr.split(","));
if (CollectionUtils.isEmpty(includePaths)) {
return false;
}
return includePaths.stream().anyMatch(uri::startsWith);
}
protected boolean isInternalRequest(HttpServletRequest request) {
String internal = request.getHeader(UserConstants.INTERNAL);

View File

@@ -1,15 +1,15 @@
package com.tencent.supersonic.auth.authentication.domain.interceptor;
package com.tencent.supersonic.auth.authentication.interceptor;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.auth.authentication.application.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
import com.tencent.supersonic.common.exception.AccessException;
import com.tencent.supersonic.common.util.context.ContextUtils;
import com.tencent.supersonic.common.util.context.S2ThreadContext;
import com.tencent.supersonic.common.util.context.ThreadContext;
import com.tencent.supersonic.auth.authentication.service.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
import com.tencent.supersonic.common.pojo.exception.AccessException;
import com.tencent.supersonic.common.util.ContextUtils;
import com.tencent.supersonic.common.util.S2ThreadContext;
import com.tencent.supersonic.common.util.ThreadContext;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -35,14 +35,21 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
setFakerUser(request);
return true;
}
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
AuthenticationIgnore ignore = method.getAnnotation(AuthenticationIgnore.class);
if (ignore != null) {
return true;
}
}
String uri = request.getServletPath();
if (!isIncludedUri(uri)) {
return true;
}
if (isExcludedUri(uri)) {
return true;
}

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.auth.authentication.domain.interceptor;
package com.tencent.supersonic.auth.authentication.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.SpringFactoriesLoader;

View File

@@ -1,7 +1,6 @@
package com.tencent.supersonic.auth.authentication.domain.dataobject;
package com.tencent.supersonic.auth.authentication.persistence.dataobject;
public class UserDO {
/**
*
*/
@@ -28,6 +27,12 @@ public class UserDO {
private String email;
/**
*
*/
private Integer isAdmin;
/**
*
* @return id
*/
public Long getId() {
@@ -35,6 +40,7 @@ public class UserDO {
}
/**
*
* @param id
*/
public void setId(Long id) {
@@ -42,6 +48,7 @@ public class UserDO {
}
/**
*
* @return name
*/
public String getName() {
@@ -49,6 +56,7 @@ public class UserDO {
}
/**
*
* @param name
*/
public void setName(String name) {
@@ -56,6 +64,7 @@ public class UserDO {
}
/**
*
* @return password
*/
public String getPassword() {
@@ -63,6 +72,7 @@ public class UserDO {
}
/**
*
* @param password
*/
public void setPassword(String password) {
@@ -70,6 +80,7 @@ public class UserDO {
}
/**
*
* @return display_name
*/
public String getDisplayName() {
@@ -77,6 +88,7 @@ public class UserDO {
}
/**
*
* @param displayName
*/
public void setDisplayName(String displayName) {
@@ -84,6 +96,7 @@ public class UserDO {
}
/**
*
* @return email
*/
public String getEmail() {
@@ -91,9 +104,26 @@ public class UserDO {
}
/**
*
* @param email
*/
public void setEmail(String email) {
this.email = email == null ? null : email.trim();
}
/**
*
* @return is_admin
*/
public Integer getIsAdmin() {
return isAdmin;
}
/**
*
* @param isAdmin
*/
public void setIsAdmin(Integer isAdmin) {
this.isAdmin = isAdmin;
}
}

View File

@@ -1,10 +1,9 @@
package com.tencent.supersonic.auth.authentication.domain.dataobject;
package com.tencent.supersonic.auth.authentication.persistence.dataobject;
import java.util.ArrayList;
import java.util.List;
public class UserDOExample {
/**
* s2_user
*/
@@ -31,6 +30,7 @@ public class UserDOExample {
protected Integer limitEnd;
/**
*
* @mbg.generated
*/
public UserDOExample() {
@@ -38,13 +38,7 @@ public class UserDOExample {
}
/**
* @mbg.generated
*/
public String getOrderByClause() {
return orderByClause;
}
/**
*
* @mbg.generated
*/
public void setOrderByClause(String orderByClause) {
@@ -52,13 +46,15 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
public boolean isDistinct() {
return distinct;
public String getOrderByClause() {
return orderByClause;
}
/**
*
* @mbg.generated
*/
public void setDistinct(boolean distinct) {
@@ -66,6 +62,15 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
public boolean isDistinct() {
return distinct;
}
/**
*
* @mbg.generated
*/
public List<Criteria> getOredCriteria() {
@@ -73,6 +78,7 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
public void or(Criteria criteria) {
@@ -80,6 +86,7 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
public Criteria or() {
@@ -89,6 +96,7 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
public Criteria createCriteria() {
@@ -100,6 +108,7 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
protected Criteria createCriteriaInternal() {
@@ -108,6 +117,7 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
public void clear() {
@@ -117,6 +127,15 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
public void setLimitStart(Integer limitStart) {
this.limitStart=limitStart;
}
/**
*
* @mbg.generated
*/
public Integer getLimitStart() {
@@ -124,31 +143,25 @@ public class UserDOExample {
}
/**
*
* @mbg.generated
*/
public void setLimitStart(Integer limitStart) {
this.limitStart = limitStart;
public void setLimitEnd(Integer limitEnd) {
this.limitEnd=limitEnd;
}
/**
*
* @mbg.generated
*/
public Integer getLimitEnd() {
return limitEnd;
}
/**
* @mbg.generated
*/
public void setLimitEnd(Integer limitEnd) {
this.limitEnd = limitEnd;
}
/**
* s2_user null
*/
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
@@ -528,6 +541,66 @@ public class UserDOExample {
addCriterion("email not between", value1, value2, "email");
return (Criteria) this;
}
public Criteria andIsAdminIsNull() {
addCriterion("is_admin is null");
return (Criteria) this;
}
public Criteria andIsAdminIsNotNull() {
addCriterion("is_admin is not null");
return (Criteria) this;
}
public Criteria andIsAdminEqualTo(Integer value) {
addCriterion("is_admin =", value, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminNotEqualTo(Integer value) {
addCriterion("is_admin <>", value, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminGreaterThan(Integer value) {
addCriterion("is_admin >", value, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminGreaterThanOrEqualTo(Integer value) {
addCriterion("is_admin >=", value, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminLessThan(Integer value) {
addCriterion("is_admin <", value, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminLessThanOrEqualTo(Integer value) {
addCriterion("is_admin <=", value, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminIn(List<Integer> values) {
addCriterion("is_admin in", values, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminNotIn(List<Integer> values) {
addCriterion("is_admin not in", values, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminBetween(Integer value1, Integer value2) {
addCriterion("is_admin between", value1, value2, "isAdmin");
return (Criteria) this;
}
public Criteria andIsAdminNotBetween(Integer value1, Integer value2) {
addCriterion("is_admin not between", value1, value2, "isAdmin");
return (Criteria) this;
}
}
/**
@@ -544,7 +617,6 @@ public class UserDOExample {
* s2_user null
*/
public static class Criterion {
private String condition;
private Object value;
@@ -561,6 +633,38 @@ public class UserDOExample {
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
@@ -596,37 +700,5 @@ public class UserDOExample {
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
}
}

View File

@@ -0,0 +1,22 @@
package com.tencent.supersonic.auth.authentication.persistence.mapper;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserDOMapper {
/**
* @mbg.generated
*/
int insert(UserDO record);
/**
* @mbg.generated
*/
List<UserDO> selectByExample(UserDOExample example);
}

View File

@@ -1,10 +1,10 @@
package com.tencent.supersonic.auth.authentication.infrastructure.repository;
package com.tencent.supersonic.auth.authentication.persistence.repository.impl;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDOExample;
import com.tencent.supersonic.auth.authentication.domain.repository.UserRepository;
import com.tencent.supersonic.auth.authentication.infrastructure.mapper.UserDOMapper;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample;
import com.tencent.supersonic.auth.authentication.persistence.repository.UserRepository;
import com.tencent.supersonic.auth.authentication.persistence.mapper.UserDOMapper;
import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Component;

View File

@@ -1,6 +1,6 @@
package com.tencent.supersonic.auth.authentication.domain.repository;
package com.tencent.supersonic.auth.authentication.persistence.repository;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
import java.util.List;
public interface UserRepository {

View File

@@ -1,19 +1,22 @@
package com.tencent.supersonic.auth.authentication.rest;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PathVariable;
@RestController
@RequestMapping("/api/auth/user")
@@ -32,7 +35,6 @@ public class UserController {
return UserHolder.findUser(httpServletRequest, httpServletResponse);
}
@GetMapping("/getUserNames")
public List<String> getUserNames() {
return userService.getUserNames();
@@ -43,6 +45,21 @@ public class UserController {
return userService.getUserList();
}
@GetMapping("/getOrganizationTree")
public List<Organization> getOrganizationTree() {
return userService.getOrganizationTree();
}
@GetMapping("/getUserAllOrgId/{userName}")
public Set<String> getUserAllOrgId(@PathVariable("userName") String userName) {
return userService.getUserAllOrgId(userName);
}
@GetMapping("/getUserByOrg/{org}")
public List<User> getUserByOrg(@PathVariable("org") String org) {
return userService.getUserByOrg(org);
}
@PostMapping("/register")
public void register(@RequestBody UserReq userCmd) {
userService.register(userCmd);

View File

@@ -0,0 +1,52 @@
package com.tencent.supersonic.auth.authentication.service;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.auth.authentication.utils.ComponentFactory;
import java.util.List;
import java.util.Set;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Override
public List<String> getUserNames() {
return ComponentFactory.getUserAdaptor().getUserNames();
}
@Override
public List<User> getUserList() {
return ComponentFactory.getUserAdaptor().getUserList();
}
@Override
public Set<String> getUserAllOrgId(String userName) {
return ComponentFactory.getUserAdaptor().getUserAllOrgId(userName);
}
@Override
public List<User> getUserByOrg(String key) {
return ComponentFactory.getUserAdaptor().getUserByOrg(key);
}
@Override
public List<Organization> getOrganizationTree() {
return ComponentFactory.getUserAdaptor().getOrganizationTree();
}
@Override
public void register(UserReq userReq) {
ComponentFactory.getUserAdaptor().register(userReq);
}
@Override
public String login(UserReq userReq) {
return ComponentFactory.getUserAdaptor().login(userReq);
}
}

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.auth.authentication.domain.strategy;
package com.tencent.supersonic.auth.authentication.strategy;
import com.tencent.supersonic.auth.api.authentication.pojo.User;

View File

@@ -1,8 +1,8 @@
package com.tencent.supersonic.auth.authentication.domain.strategy;
package com.tencent.supersonic.auth.authentication.strategy;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.auth.authentication.domain.strategy;
package com.tencent.supersonic.auth.authentication.strategy;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;

View File

@@ -0,0 +1,23 @@
package com.tencent.supersonic.auth.authentication.utils;
import com.tencent.supersonic.auth.api.authentication.adaptor.UserAdaptor;
import org.springframework.core.io.support.SpringFactoriesLoader;
import java.util.Objects;
public class ComponentFactory {
private static UserAdaptor userAdaptor;
public static UserAdaptor getUserAdaptor() {
if (Objects.isNull(userAdaptor)) {
userAdaptor = init(UserAdaptor.class);
}
return userAdaptor;
}
private static <T> T init(Class<T> factoryType) {
return SpringFactoriesLoader.loadFactories(factoryType,
Thread.currentThread().getContextClassLoader()).get(0);
}
}

View File

@@ -1,7 +1,8 @@
package com.tencent.supersonic.auth.authentication.domain.utils;
package com.tencent.supersonic.auth.authentication.utils;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_ALGORITHM;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_CREATE_TIME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_IS_ADMIN;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_PREFIX;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_TIME_OUT;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_DISPLAY_NAME;
@@ -9,11 +10,10 @@ import static com.tencent.supersonic.auth.api.authentication.constant.UserConsta
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_ID;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_NAME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_PASSWORD;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.common.exception.AccessException;
import com.tencent.supersonic.common.pojo.exception.AccessException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@@ -22,9 +22,11 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class UserTokenUtils {
@@ -41,6 +43,7 @@ public class UserTokenUtils {
claims.put(TOKEN_USER_PASSWORD, StringUtils.isEmpty(user.getPassword()) ? "" : user.getPassword());
claims.put(TOKEN_USER_DISPLAY_NAME, user.getDisplayName());
claims.put(TOKEN_CREATE_TIME, System.currentTimeMillis());
claims.put(TOKEN_IS_ADMIN, user.getIsAdmin());
return generate(claims);
}
@@ -51,6 +54,7 @@ public class UserTokenUtils {
claims.put(TOKEN_USER_PASSWORD, "admin");
claims.put(TOKEN_USER_DISPLAY_NAME, "admin");
claims.put(TOKEN_CREATE_TIME, System.currentTimeMillis());
claims.put(TOKEN_IS_ADMIN, 1);
return generate(claims);
}
@@ -62,13 +66,17 @@ public class UserTokenUtils {
String userName = String.valueOf(claims.get(TOKEN_USER_NAME));
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
String displayName = String.valueOf(claims.get(TOKEN_USER_DISPLAY_NAME));
return User.get(userId, userName, displayName, email);
Integer isAdmin = claims.get(TOKEN_IS_ADMIN) == null
? 0 : Integer.parseInt(claims.get(TOKEN_IS_ADMIN).toString());
return User.get(userId, userName, displayName, email, isAdmin);
}
public UserWithPassword getUserWithPassword(HttpServletRequest request) {
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
if (StringUtils.isBlank(token)) {
throw new AccessException("token is blank, get user failed");
String message = "token is blank, get user failed";
log.warn("{}, uri: {}", message, request.getServletPath());
throw new AccessException(message);
}
final Claims claims = getClaims(token);
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
@@ -76,7 +84,9 @@ public class UserTokenUtils {
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
String displayName = String.valueOf(claims.get(TOKEN_USER_DISPLAY_NAME));
String password = String.valueOf(claims.get(TOKEN_USER_PASSWORD));
return UserWithPassword.get(userId, userName, displayName, email, password);
Integer isAdmin = claims.get(TOKEN_IS_ADMIN) == null
? 0 : Integer.parseInt(claims.get(TOKEN_IS_ADMIN).toString());
return UserWithPassword.get(userId, userName, displayName, email, password, isAdmin);
}
private Claims getClaims(String token) {

View File

@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tencent.supersonic.auth.authentication.infrastructure.mapper.UserDOMapper">
<resultMap id="BaseResultMap" type="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
<id column="id" jdbcType="BIGINT" property="id" />
<mapper namespace="com.tencent.supersonic.auth.authentication.persistence.mapper.UserDOMapper">
<resultMap id="BaseResultMap" type="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
<result column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="display_name" jdbcType="VARCHAR" property="displayName" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="is_admin" jdbcType="INTEGER" property="isAdmin" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@@ -38,9 +39,9 @@
</where>
</sql>
<sql id="Base_Column_List">
id, name, password, display_name, email
id, name, password, display_name, email, is_admin
</sql>
<select id="selectByExample" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDOExample" resultMap="BaseResultMap">
<select id="selectByExample" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
@@ -57,23 +58,15 @@
limit #{limitStart} , #{limitEnd}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from s2_user
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from s2_user
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
<insert id="insert" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
insert into s2_user (id, name, password,
display_name, email)
display_name, email, is_admin
)
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
#{displayName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR})
#{displayName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{isAdmin,jdbcType=INTEGER}
)
</insert>
<insert id="insertSelective" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
<insert id="insertSelective" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
insert into s2_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
@@ -91,6 +84,9 @@
<if test="email != null">
email,
</if>
<if test="isAdmin != null">
is_admin,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@@ -108,38 +104,15 @@
<if test="email != null">
#{email,jdbcType=VARCHAR},
</if>
<if test="isAdmin != null">
#{isAdmin,jdbcType=INTEGER},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDOExample" resultType="java.lang.Long">
<select id="countByExample" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample" resultType="java.lang.Long">
select count(*) from s2_user
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByPrimaryKeySelective" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
update s2_user
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="password != null">
password = #{password,jdbcType=VARCHAR},
</if>
<if test="displayName != null">
display_name = #{displayName,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{email,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
update s2_user
set name = #{name,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR},
display_name = #{displayName,jdbcType=VARCHAR},
email = #{email,jdbcType=VARCHAR}
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>

View File

@@ -35,10 +35,6 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>auth-authentication</artifactId>

View File

@@ -2,14 +2,14 @@ package com.tencent.supersonic.auth.authorization.application;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthResGrp;
import com.tencent.supersonic.auth.api.authorization.pojo.DimensionFilter;
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
import com.tencent.supersonic.auth.api.authorization.service.AuthService;
import javax.servlet.http.HttpServletRequest;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthGroup;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRule;
import lombok.extern.slf4j.Slf4j;
@@ -17,11 +17,11 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Map;
import java.util.ArrayList;
import java.util.stream.Collectors;
@Service
@@ -30,8 +30,12 @@ public class AuthServiceImpl implements AuthService {
private JdbcTemplate jdbcTemplate;
public AuthServiceImpl(JdbcTemplate jdbcTemplate) {
private UserService userService;
public AuthServiceImpl(JdbcTemplate jdbcTemplate,
UserService userService) {
this.jdbcTemplate = jdbcTemplate;
this.userService = userService;
}
private List<AuthGroup> load() {
@@ -41,15 +45,15 @@ public class AuthServiceImpl implements AuthService {
}
@Override
public List<AuthGroup> queryAuthGroups(String domainId, Integer groupId) {
public List<AuthGroup> queryAuthGroups(String modelId, Integer groupId) {
return load().stream()
.filter(group -> (Objects.isNull(groupId) || groupId.equals(group.getGroupId()))
&& domainId.equals(group.getDomainId()))
&& modelId.equals(group.getModelId()))
.collect(Collectors.toList());
}
@Override
public void updateAuthGroup(AuthGroup group) {
public void addOrUpdateAuthGroup(AuthGroup group) {
Gson g = new Gson();
if (group.getGroupId() == null) {
int nextGroupId = 1;
@@ -74,19 +78,23 @@ public class AuthServiceImpl implements AuthService {
@Override
public AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, HttpServletRequest request) {
List<AuthGroup> groups = getAuthGroups(req);
public AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, User user) {
Set<String> userOrgIds = userService.getUserAllOrgId(user.getName());
if (!CollectionUtils.isEmpty(userOrgIds)) {
req.setDepartmentIds(new ArrayList<>(userOrgIds));
}
List<AuthGroup> groups = getAuthGroups(req, user.getName());
AuthorizedResourceResp resource = new AuthorizedResourceResp();
Map<String, List<AuthGroup>> authGroupsByDomainId = groups.stream()
.collect(Collectors.groupingBy(AuthGroup::getDomainId));
Map<String, List<AuthGroup>> authGroupsByModelId = groups.stream()
.collect(Collectors.groupingBy(AuthGroup::getModelId));
Map<String, List<AuthRes>> reqAuthRes = req.getResources().stream()
.collect(Collectors.groupingBy(AuthRes::getDomainId));
.collect(Collectors.groupingBy(AuthRes::getModelId));
for (String domainId : reqAuthRes.keySet()) {
List<AuthRes> reqResourcesList = reqAuthRes.get(domainId);
for (String modelId : reqAuthRes.keySet()) {
List<AuthRes> reqResourcesList = reqAuthRes.get(modelId);
AuthResGrp rg = new AuthResGrp();
if (authGroupsByDomainId.containsKey(domainId)) {
List<AuthGroup> authGroups = authGroupsByDomainId.get(domainId);
if (authGroupsByModelId.containsKey(modelId)) {
List<AuthGroup> authGroups = authGroupsByModelId.get(modelId);
for (AuthRes reqRes : reqResourcesList) {
for (AuthGroup authRuleGroup : authGroups) {
List<AuthRule> authRules = authRuleGroup.getAuthRules();
@@ -105,8 +113,8 @@ public class AuthServiceImpl implements AuthService {
}
}
if (StringUtils.isNotEmpty(req.getDomainId())) {
List<AuthGroup> authGroups = authGroupsByDomainId.get(req.getDomainId());
if (StringUtils.isNotEmpty(req.getModelId())) {
List<AuthGroup> authGroups = authGroupsByModelId.get(req.getModelId());
if (!CollectionUtils.isEmpty(authGroups)) {
for (AuthGroup group : authGroups) {
if (group.getDimensionFilters() != null
@@ -119,29 +127,28 @@ public class AuthServiceImpl implements AuthService {
}
}
}
return resource;
}
private List<AuthGroup> getAuthGroups(QueryAuthResReq req) {
List<AuthGroup> groups = load().stream().
filter(group -> {
if (!Objects.equals(group.getDomainId(), req.getDomainId())) {
private List<AuthGroup> getAuthGroups(QueryAuthResReq req, String userName) {
List<AuthGroup> groups = load().stream()
.filter(group -> {
if (!Objects.equals(group.getModelId(), req.getModelId())) {
return false;
}
if (!CollectionUtils.isEmpty(group.getAuthorizedUsers()) && group.getAuthorizedUsers()
.contains(req.getUser())) {
.contains(userName)) {
return true;
}
for (String deparmentId : req.getDepartmentIds()) {
for (String departmentId : req.getDepartmentIds()) {
if (!CollectionUtils.isEmpty(group.getAuthorizedDepartmentIds())
&& group.getAuthorizedDepartmentIds().contains(deparmentId)) {
&& group.getAuthorizedDepartmentIds().contains(departmentId)) {
return true;
}
}
return false;
}).collect(Collectors.toList());
log.info("user:{} department:{} authGroups:{}", req.getUser(), req.getDepartmentIds(), groups);
log.info("user:{} department:{} authGroups:{}", userName, req.getDepartmentIds(), groups);
return groups;
}

View File

@@ -1,11 +1,14 @@
package com.tencent.supersonic.auth.authorization.rest;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
import com.tencent.supersonic.auth.api.authorization.service.AuthService;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthGroup;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -26,9 +29,9 @@ public class AuthController {
}
@GetMapping("/queryGroup")
public List<AuthGroup> queryAuthGroup(@RequestParam("domainId") String domainId,
public List<AuthGroup> queryAuthGroup(@RequestParam("modelId") String modelId,
@RequestParam(value = "groupId", required = false) Integer groupId) {
return authService.queryAuthGroups(domainId, groupId);
return authService.queryAuthGroups(modelId, groupId);
}
/**
@@ -37,7 +40,7 @@ public class AuthController {
@PostMapping("/createGroup")
public void newAuthGroup(@RequestBody AuthGroup group) {
group.setGroupId(null);
authService.updateAuthGroup(group);
authService.addOrUpdateAuthGroup(group);
}
@PostMapping("/removeGroup")
@@ -55,19 +58,20 @@ public class AuthController {
if (group.getGroupId() == null || group.getGroupId() == 0) {
throw new RuntimeException("groupId is empty");
}
authService.updateAuthGroup(group);
authService.addOrUpdateAuthGroup(group);
}
/**
* 查询有权限访问的受限资源id
*
* @param req
* @param request
* @return
*/
@PostMapping("/queryAuthorizedRes")
public AuthorizedResourceResp queryAuthorizedResources(@RequestBody QueryAuthResReq req,
HttpServletRequest request) {
return authService.queryAuthorizedResources(req, request);
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return authService.queryAuthorizedResources(req, user);
}
}

View File

@@ -1,15 +1,12 @@
package com.tencent.supersonic.chat.api.component;
import com.tencent.supersonic.chat.api.request.QueryContextReq;
import com.tencent.supersonic.chat.api.pojo.QueryContext;
/**
* This interface defines the contract for a schema mapper that identifies references to schema
* elements in natural language queries.
*
* The schema mapper matches queries against the knowledge base which is constructed using the
* schema of semantic models.
* A schema mapper identifies references to schema elements(metrics/dimensions/entities/values)
* in user queries. It matches the query text against the knowledge base.
*/
public interface SchemaMapper {
void map(QueryContextReq queryContext);
void map(QueryContext queryContext);
}

View File

@@ -0,0 +1,13 @@
package com.tencent.supersonic.chat.api.component;
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
import net.sf.jsqlparser.JSQLParserException;
/**
* A semantic corrector checks validity of extracted semantic information and
* performs correction and optimization if needed.
*/
public interface SemanticCorrector {
void correct(SemanticCorrectInfo semanticCorrectInfo) throws JSQLParserException;
}

View File

@@ -0,0 +1,60 @@
package com.tencent.supersonic.chat.api.component;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
import com.tencent.supersonic.common.pojo.enums.AuthType;
import com.tencent.supersonic.semantic.api.model.request.PageDimensionReq;
import com.tencent.supersonic.semantic.api.model.request.PageMetricReq;
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
import com.tencent.supersonic.semantic.api.model.response.ExplainResp;
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
import com.tencent.supersonic.semantic.api.query.request.ExplainSqlReq;
import com.tencent.supersonic.semantic.api.query.request.QueryDimValueReq;
import com.tencent.supersonic.semantic.api.query.request.QueryDslReq;
import com.tencent.supersonic.semantic.api.query.request.QueryMultiStructReq;
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
import java.util.List;
/**
* A semantic layer provides a simplified and consistent view of data from multiple sources.
* It abstracts away the complexity of the underlying data sources and provides a unified view
* of the data that is easier to understand and use.
* <p>
* The interface defines methods for getting metadata as well as querying data in the semantic layer.
* Implementations of this interface should provide concrete implementations that interact with the
* underlying data sources and return results in a consistent format. Or it can be implemented
* as proxy to a remote semantic service.
* </p>
*/
public interface SemanticInterpreter {
QueryResultWithSchemaResp queryByStruct(QueryStructReq queryStructReq, User user);
QueryResultWithSchemaResp queryByMultiStruct(QueryMultiStructReq queryMultiStructReq, User user);
QueryResultWithSchemaResp queryByDsl(QueryDslReq queryDslReq, User user);
QueryResultWithSchemaResp queryDimValue(QueryDimValueReq queryDimValueReq, User user);
List<ModelSchema> getModelSchema();
List<ModelSchema> getModelSchema(List<Long> ids);
ModelSchema getModelSchema(Long model, Boolean cacheEnable);
PageInfo<DimensionResp> getDimensionPage(PageDimensionReq pageDimensionCmd);
PageInfo<MetricResp> getMetricPage(PageMetricReq pageMetricCmd, User user);
List<DomainResp> getDomainList(User user);
List<ModelResp> getModelList(AuthType authType, Long domainId, User user);
<T> ExplainResp explain(ExplainSqlReq<T> explainSqlReq, User user) throws Exception;
}

View File

@@ -1,51 +0,0 @@
package com.tencent.supersonic.chat.api.component;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.semantic.api.core.request.PageDimensionReq;
import com.tencent.supersonic.semantic.api.core.request.PageMetricReq;
import com.tencent.supersonic.semantic.api.core.response.*;
import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq;
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
import java.util.List;
/**
* This interface defines the contract for a semantic layer that provides a simplified and
* consistent view of data from multiple sources.
* The semantic layer abstracts away the complexity of the underlying data sources and provides
* a unified view of the data that is easier to understand and use.
* <p>
* The interface defines methods for getting metadata as well as querying data in the semantic layer.
* Implementations of this interface should provide concrete implementations that interact with the
* underlying data sources and return results in a consistent format. Or it can be implemented
* as proxy to a remote semantic service.
* </p>
*/
public interface SemanticLayer {
QueryResultWithSchemaResp queryByStruct(QueryStructReq queryStructReq, User user);
QueryResultWithSchemaResp queryBySql(QuerySqlReq querySqlReq, User user);
DomainSchemaResp getDomainSchemaInfo(Long domain, Boolean cacheEnable);
List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids);
List<DomainResp> getDomainListForViewer();
List<DomainResp> getDomainListForAdmin();
PageInfo<DimensionResp> queryDimensionPage(PageDimensionReq pageDimensionCmd);
PageInfo<MetricResp> queryMetricPage(PageMetricReq pageMetricCmd);
// PageInfo<MetricResp> queryMetricPage(PageMetricReq pageMetricCmd);
//
// PageInfo<DimensionResp> queryDimensionPage(PageDimensionReq pageDimensionCmd);
//
// List<DomainResp> getDomainListForAdmin();
//
// List<DomainResp> getDomainListForViewer();
}

View File

@@ -2,16 +2,14 @@ package com.tencent.supersonic.chat.api.component;
import com.tencent.supersonic.chat.api.pojo.ChatContext;
import com.tencent.supersonic.chat.api.request.QueryContextReq;
import com.tencent.supersonic.chat.api.pojo.QueryContext;
/**
* This interface defines the contract for a semantic parser that can analyze natural language query
* and extract meaning from it.
*
* The semantic parser uses either rule-based or model-based algorithms to identify query intent
* and related semantic items described in the query.
* A semantic parser understands user queries and extracts semantic information.
* It could leverage either rule-based or LLM-based approach to identify query intent
* and extract related semantic items from the query.
*/
public interface SemanticParser {
void parse(QueryContextReq queryContext, ChatContext chatContext);
void parse(QueryContext queryContext, ChatContext chatContext);
}

View File

@@ -2,17 +2,22 @@ package com.tencent.supersonic.chat.api.component;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.chat.api.response.QueryResultResp;
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
import com.tencent.supersonic.semantic.api.model.response.ExplainResp;
import org.apache.calcite.sql.parser.SqlParseException;
/**
* This class defines the contract for a semantic query that executes specific type of
* query based on the results of semantic parsing.
* A semantic query executes specific type of query based on the results of semantic parsing.
*/
public interface SemanticQuery {
String getQueryMode();
QueryResultResp execute(User user);
QueryResult execute(User user) throws SqlParseException;
ExplainResp explain(User user);
SemanticParseInfo getParseInfo();
void setParseInfo(SemanticParseInfo parseInfo);
}

View File

@@ -6,6 +6,7 @@ import lombok.Data;
public class ChatContext {
private Integer chatId;
private Integer agentId;
private String queryText;
private SemanticParseInfo parseInfo = new SemanticParseInfo();
private String user;

View File

@@ -1,12 +0,0 @@
package com.tencent.supersonic.chat.api.pojo;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
@Data
public class DomainInfo extends DataInfo implements Serializable {
private List<String> words;
private String primaryEntityBizName;
}

View File

@@ -0,0 +1,47 @@
package com.tencent.supersonic.chat.api.pojo;
import lombok.Data;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
@Data
public class ModelSchema {
private SchemaElement model;
private Set<SchemaElement> metrics = new HashSet<>();
private Set<SchemaElement> dimensions = new HashSet<>();
private Set<SchemaElement> dimensionValues = new HashSet<>();
private SchemaElement entity = new SchemaElement();
public SchemaElement getElement(SchemaElementType elementType, long elementID) {
Optional<SchemaElement> element = Optional.empty();
switch (elementType) {
case ENTITY:
element = Optional.ofNullable(entity);
break;
case MODEL:
element = Optional.of(model);
break;
case METRIC:
element = metrics.stream().filter(e -> e.getId() == elementID).findFirst();
break;
case DIMENSION:
element = dimensions.stream().filter(e -> e.getId() == elementID).findFirst();
break;
case VALUE:
element = dimensionValues.stream().filter(e -> e.getId() == elementID).findFirst();
break;
default:
}
if (element.isPresent()) {
return element.get();
} else {
return null;
}
}
}

View File

@@ -0,0 +1,22 @@
package com.tencent.supersonic.chat.api.pojo;
import com.tencent.supersonic.chat.api.component.SemanticQuery;
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
public class QueryContext {
private QueryReq request;
private List<SemanticQuery> candidateQueries = new ArrayList<>();
private SchemaMapInfo mapInfo = new SchemaMapInfo();
public QueryContext(QueryReq request) {
this.request = request;
}
}

View File

@@ -1,12 +0,0 @@
package com.tencent.supersonic.chat.api.pojo;
import lombok.Data;
@Data
public class QueryMatchInfo {
SchemaElementType elementType;
String detectWord;
private Integer count = 0;
private double maxSimilarity;
}

View File

@@ -0,0 +1,52 @@
package com.tencent.supersonic.chat.api.pojo;
import com.google.common.base.Objects;
import java.io.Serializable;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Data
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SchemaElement implements Serializable {
private Long model;
private Long id;
private String name;
private String bizName;
private Long useCnt;
private SchemaElementType type;
private List<String> alias;
private List<SchemaValueMap> schemaValueMaps;
private String defaultAgg;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SchemaElement schemaElement = (SchemaElement) o;
return Objects.equal(model, schemaElement.model) && Objects.equal(id,
schemaElement.id) && Objects.equal(name, schemaElement.name)
&& Objects.equal(bizName, schemaElement.bizName) && Objects.equal(
useCnt, schemaElement.useCnt) && Objects.equal(type, schemaElement.type);
}
@Override
public int hashCode() {
return Objects.hashCode(model, id, name, bizName, useCnt, type);
}
}

View File

@@ -13,15 +13,11 @@ import lombok.ToString;
@NoArgsConstructor
public class SchemaElementMatch {
SchemaElementType elementType;
int elementID;
SchemaElement element;
double similarity;
String detectWord;
String word;
Long frequency;
boolean isInherited;
}

View File

@@ -1,7 +1,7 @@
package com.tencent.supersonic.chat.api.pojo;
public enum SchemaElementType {
DOMAIN,
MODEL,
METRIC,
DIMENSION,
VALUE,

View File

@@ -7,26 +7,25 @@ import java.util.Set;
public class SchemaMapInfo {
private Map<Integer, List<SchemaElementMatch>> domainElementMatches = new HashMap<>();
private Map<Long, List<SchemaElementMatch>> modelElementMatches = new HashMap<>();
public Set<Integer> getMatchedDomains() {
return domainElementMatches.keySet();
public Set<Long> getMatchedModels() {
return modelElementMatches.keySet();
}
public List<SchemaElementMatch> getMatchedElements(Integer domain) {
return domainElementMatches.get(domain);
public List<SchemaElementMatch> getMatchedElements(Long model) {
return modelElementMatches.get(model);
}
public Map<Integer, List<SchemaElementMatch>> getDomainElementMatches() {
return domainElementMatches;
public Map<Long, List<SchemaElementMatch>> getModelElementMatches() {
return modelElementMatches;
}
public void setDomainElementMatches(
Map<Integer, List<SchemaElementMatch>> domainElementMatches) {
this.domainElementMatches = domainElementMatches;
public void setModelElementMatches(Map<Long, List<SchemaElementMatch>> modelElementMatches) {
this.modelElementMatches = modelElementMatches;
}
public void setMatchedElements(Integer domain, List<SchemaElementMatch> elementMatches) {
domainElementMatches.put(domain, elementMatches);
public void setMatchedElements(Long model, List<SchemaElementMatch> elementMatches) {
modelElementMatches.put(model, elementMatches);
}
}

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.chat.api.pojo;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Data
public class SchemaValueMap {
/**
* dimension value in db
*/
private String techName;
/**
* dimension value for result show
*/
private String bizName;
/**
* dimension value for user query
*/
private List<String> alias = new ArrayList<>();
}

View File

@@ -0,0 +1,22 @@
package com.tencent.supersonic.chat.api.pojo;
import com.tencent.supersonic.chat.api.pojo.request.QueryFilters;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class SemanticCorrectInfo {
private QueryFilters queryFilters;
private SemanticParseInfo parseInfo;
private String sql;
private String preSql;
}

View File

@@ -1,34 +1,73 @@
package com.tencent.supersonic.chat.api.pojo;
import com.tencent.supersonic.common.enums.AggregateTypeEnum;
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
import com.tencent.supersonic.chat.api.pojo.response.SqlInfo;
import com.tencent.supersonic.common.pojo.DateConf;
import com.tencent.supersonic.common.pojo.Order;
import com.tencent.supersonic.common.pojo.SchemaItem;
import com.tencent.supersonic.common.pojo.enums.AggregateTypeEnum;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import com.tencent.supersonic.common.pojo.enums.FilterType;
import lombok.Data;
@Data
public class SemanticParseInfo {
String queryMode;
AggregateTypeEnum aggType = AggregateTypeEnum.NONE;
Long domainId = 0L;
String domainName;
Long entity = 0L;
Set<SchemaItem> metrics = new LinkedHashSet();
Set<SchemaItem> dimensions = new LinkedHashSet();
Set<Filter> dimensionFilters = new LinkedHashSet();
Set<Filter> metricFilters = new LinkedHashSet();
private Integer id;
private String queryMode;
private SchemaElement model;
private Set<SchemaElement> metrics = new TreeSet<>(new SchemaNameLengthComparator());
private Set<SchemaElement> dimensions = new LinkedHashSet();
private SchemaElement entity;
private AggregateTypeEnum aggType = AggregateTypeEnum.NONE;
private FilterType filterType = FilterType.UNION;
private Set<QueryFilter> dimensionFilters = new LinkedHashSet();
private Set<QueryFilter> metricFilters = new LinkedHashSet();
private Set<Order> orders = new LinkedHashSet();
private DateConf dateInfo;
private Long limit;
private Boolean nativeQuery = false;
private Double bonus = 0d;
private double score;
private List<SchemaElementMatch> elementMatches = new ArrayList<>();
private Object info;
private Map<String, Object> properties = new HashMap<>();
private EntityInfo entityInfo;
private SqlInfo sqlInfo = new SqlInfo();
public Long getModelId() {
return model != null ? model.getId() : 0L;
}
public String getModelName() {
return model != null ? model.getName() : "null";
}
private static class SchemaNameLengthComparator implements Comparator<SchemaElement> {
@Override
public int compare(SchemaElement o1, SchemaElement o2) {
int len1 = o1.getName().length();
int len2 = o2.getName().length();
if (len1 != len2) {
return len1 - len2;
} else {
return o1.getName().compareTo(o2.getName());
}
}
}
public Set<SchemaElement> getMetrics() {
Set<SchemaElement> metricSet = new TreeSet<>(new SchemaNameLengthComparator());
metricSet.addAll(metrics);
metrics = metricSet;
return metrics;
}
}

View File

@@ -0,0 +1,71 @@
package com.tencent.supersonic.chat.api.pojo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class SemanticSchema implements Serializable {
private List<ModelSchema> modelSchemaList;
public SemanticSchema(List<ModelSchema> modelSchemaList) {
this.modelSchemaList = modelSchemaList;
}
public void add(ModelSchema schema) {
modelSchemaList.add(schema);
}
public Map<Long, String> getModelIdToName() {
return modelSchemaList.stream()
.collect(Collectors.toMap(a -> a.getModel().getId(), a -> a.getModel().getName(), (k1, k2) -> k1));
}
public List<SchemaElement> getDimensionValues() {
List<SchemaElement> dimensionValues = new ArrayList<>();
modelSchemaList.stream().forEach(d -> dimensionValues.addAll(d.getDimensionValues()));
return dimensionValues;
}
public List<SchemaElement> getDimensions() {
List<SchemaElement> dimensions = new ArrayList<>();
modelSchemaList.stream().forEach(d -> dimensions.addAll(d.getDimensions()));
return dimensions;
}
public List<SchemaElement> getDimensions(Long modelId) {
List<SchemaElement> dimensions = getDimensions();
return getElementsByModelId(modelId, dimensions);
}
public List<SchemaElement> getMetrics() {
List<SchemaElement> metrics = new ArrayList<>();
modelSchemaList.stream().forEach(d -> metrics.addAll(d.getMetrics()));
return metrics;
}
public List<SchemaElement> getMetrics(Long modelId) {
List<SchemaElement> metrics = getMetrics();
return getElementsByModelId(modelId, metrics);
}
private List<SchemaElement> getElementsByModelId(Long modelId, List<SchemaElement> elements) {
return elements.stream()
.filter(schemaElement -> modelId.equals(schemaElement.getModel()))
.collect(Collectors.toList());
}
public List<SchemaElement> getModels() {
List<SchemaElement> models = new ArrayList<>();
modelSchemaList.stream().forEach(d -> models.add(d.getModel()));
return models;
}
public List<SchemaElement> getEntities() {
List<SchemaElement> entities = new ArrayList<>();
modelSchemaList.stream().forEach(d -> entities.add(d.getEntity()));
return entities;
}
}

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
import java.util.List;
@Data
public class ChatAggConfigReq {
/**
* invisible dimensions/metrics
*/
private ItemVisibility visibility;
/**
* information about dictionary about the model
*/
private List<KnowledgeInfoReq> knowledgeInfos;
private KnowledgeAdvancedConfig globalKnowledgeConfig;
private ChatDefaultConfigReq chatDefaultConfig;
}

View File

@@ -0,0 +1,40 @@
package com.tencent.supersonic.chat.api.pojo.request;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import lombok.Data;
import lombok.ToString;
import java.util.List;
/**
* extended information command about model
*/
@Data
@ToString
public class ChatConfigBaseReq {
private Long modelId;
/**
* the chatDetailConfig about the model
*/
private ChatDetailConfigReq chatDetailConfig;
/**
* the chatAggConfig about the model
*/
private ChatAggConfigReq chatAggConfig;
/**
* the recommended questions about the model
*/
private List<RecommendedQuestionReq> recommendedQuestions;
/**
* available status
*/
private StatusEnum status;
}

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.chat.domain.pojo.config;
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;

View File

@@ -1,6 +1,6 @@
package com.tencent.supersonic.chat.domain.pojo.config;
package com.tencent.supersonic.chat.api.pojo.request;
import com.tencent.supersonic.common.enums.StatusEnum;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -10,6 +10,6 @@ import lombok.NoArgsConstructor;
public class ChatConfigFilter {
private Long id;
private Long domainId;
private Long modelId;
private StatusEnum status = StatusEnum.ONLINE;
}

View File

@@ -1,14 +1,14 @@
package com.tencent.supersonic.chat.domain.pojo.config;
package com.tencent.supersonic.chat.api.pojo.request;
import com.tencent.supersonic.common.constant.Constants;
import com.tencent.supersonic.common.pojo.Constants;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class ChatDefaultConfig {
public class ChatDefaultConfigReq {
private List<Long> dimensionIds = new ArrayList<>();
private List<Long> metricIds = new ArrayList<>();
@@ -24,4 +24,15 @@ public class ChatDefaultConfig {
*/
private String period = Constants.DAY;
private TimeMode timeMode = TimeMode.LAST;
public enum TimeMode {
/**
* date mode
* LAST - a certain time
* RECENT - a period time
*/
LAST, RECENT
}
}

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
import java.util.List;
@Data
public class ChatDetailConfigReq {
/**
* invisible dimensions/metrics
*/
private ItemVisibility visibility;
/**
* information about dictionary about the model
*/
private List<KnowledgeInfoReq> knowledgeInfos;
private KnowledgeAdvancedConfig globalKnowledgeConfig;
private ChatDefaultConfigReq chatDefaultConfig;
}

View File

@@ -0,0 +1,23 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.List;
import static java.time.LocalDate.now;
@ToString
@Data
@NoArgsConstructor
public class DictLatestTaskReq {
@NotNull
private Long modelId;
private List<Long> dimIds;
private String createdAt = now().plusDays(-4).toString();
}

View File

@@ -0,0 +1,20 @@
package com.tencent.supersonic.chat.api.pojo.request;
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
import lombok.Data;
import lombok.ToString;
@ToString
@Data
public class DictTaskFilterReq {
private Long id;
private String name;
private String createdBy;
private String createdAt;
private TaskStatusEnum status;
}

View File

@@ -0,0 +1,16 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
@Data
public class DimensionValueReq {
private Integer agentId;
private Long elementID;
private Long modelId;
private String bizName;
private Object value;
}

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.chat.domain.pojo.config;
package com.tencent.supersonic.chat.api.pojo.request;
import java.util.List;
import lombok.AllArgsConstructor;
@@ -7,7 +7,7 @@ import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* the entity info about the domain
* the entity info about the model
*/
@Data
@AllArgsConstructor

View File

@@ -0,0 +1,18 @@
package com.tencent.supersonic.chat.api.pojo.request;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
import lombok.Data;
@Data
public class ExecuteQueryReq {
private User user;
private Integer agentId;
private Integer chatId;
private String queryText;
private Long queryId = 7L;
private Integer parseId = 2;
private SemanticParseInfo parseInfo;
private boolean saveAnswer = true;
}

View File

@@ -0,0 +1,13 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class ItemNameVisibility {
private ItemNameVisibilityInfo aggVisibilityInfo;
private ItemNameVisibilityInfo detailVisibilityInfo;
}

View File

@@ -0,0 +1,23 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
import lombok.ToString;
import java.util.ArrayList;
import java.util.List;
@Data
@ToString
public class ItemNameVisibilityInfo {
/**
* invisible dimensions
*/
private List<String> blackDimNameList = new ArrayList<>();
/**
* invisible metrics
*/
private List<String> blackMetricNameList = new ArrayList<>();
}

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.chat.domain.pojo.config;
package com.tencent.supersonic.chat.api.pojo.request;
import java.util.ArrayList;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.chat.domain.pojo.config;
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;

View File

@@ -1,21 +1,20 @@
package com.tencent.supersonic.chat.domain.pojo.config;
package com.tencent.supersonic.chat.api.pojo.request;
import com.tencent.supersonic.common.enums.TypeEnums;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import java.util.List;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* information about dictionary about the domain
* information about dictionary about the model
*/
@Data
public class KnowledgeInfo {
public class KnowledgeInfoReq {
/**
* metricIdDimensionIddomainId
* metricIdDimensionIdmodelId
*/
private Long itemId;
@@ -33,6 +32,4 @@ public class KnowledgeInfo {
* advanced knowledge config for single item
*/
private KnowledgeAdvancedConfig knowledgeAdvancedConfig;
}

View File

@@ -0,0 +1,16 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
import java.util.List;
@Data
public class PageQueryInfoReq {
private int current;
private int pageSize;
private String userName;
private List<Long> ids;
}

View File

@@ -0,0 +1,21 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
@Data
public class PluginQueryReq {
private String name;
private String parseMode;
private String type;
private String model;
private String pattern;
private String createdBy;
}

View File

@@ -0,0 +1,21 @@
package com.tencent.supersonic.chat.api.pojo.request;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
import com.tencent.supersonic.common.pojo.DateConf;
import java.util.HashSet;
import java.util.Set;
import lombok.Data;
@Data
public class QueryDataReq {
private User user;
private Set<SchemaElement> metrics = new HashSet<>();
private Set<SchemaElement> dimensions = new HashSet<>();
private Set<QueryFilter> dimensionFilters = new HashSet<>();
private Set<QueryFilter> metricFilters = new HashSet<>();
private DateConf dateInfo;
private Long queryId = 7L;
private Integer parseId = 2;
}

View File

@@ -1,13 +1,13 @@
package com.tencent.supersonic.chat.api.pojo;
package com.tencent.supersonic.chat.api.pojo.request;
import com.google.common.base.Objects;
import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
import java.util.Objects;
import lombok.Data;
import lombok.ToString;
@Data
@ToString(callSuper = true)
public class Filter {
public class QueryFilter {
private String bizName;
@@ -19,6 +19,8 @@ public class Filter {
private Long elementID;
private String function;
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -27,14 +29,15 @@ public class Filter {
if (o == null || getClass() != o.getClass()) {
return false;
}
Filter filter = (Filter) o;
return Objects.equals(bizName, filter.bizName) && Objects.equals(name, filter.name)
&& operator == filter.operator && Objects.equals(value, filter.value) && Objects.equals(
elementID, filter.elementID);
QueryFilter that = (QueryFilter) o;
return Objects.equal(bizName, that.bizName) && Objects.equal(name,
that.name) && operator == that.operator && Objects.equal(value, that.value)
&& Objects.equal(elementID, that.elementID) && Objects.equal(
function, that.function);
}
@Override
public int hashCode() {
return Objects.hash(bizName, name, operator, value, elementID);
return Objects.hashCode(bizName, name, operator, value, elementID, function);
}
}

View File

@@ -1,4 +1,4 @@
package com.tencent.supersonic.chat.api.pojo;
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.Data;
import java.util.ArrayList;
@@ -7,10 +7,7 @@ import java.util.List;
import java.util.Map;
@Data
public class QueryFilter {
private List<Filter> filters = new ArrayList<>();
public class QueryFilters {
private List<QueryFilter> filters = new ArrayList<>();
private Map<String, Object> params = new HashMap<>();
}

View File

@@ -0,0 +1,15 @@
package com.tencent.supersonic.chat.api.pojo.request;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import lombok.Data;
@Data
public class QueryReq {
private String queryText;
private Integer chatId;
private Long modelId = 0L;
private User user;
private QueryFilters queryFilters;
private boolean saveAnswer = true;
private Integer agentId;
}

View File

@@ -0,0 +1,16 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class RecommendedQuestionReq {
private String question;
}

View File

@@ -0,0 +1,25 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SolvedQueryReq {
private Long queryId;
private Integer parseId;
private String queryText;
private Long modelId;
private Integer agentId;
}

View File

@@ -0,0 +1,10 @@
package com.tencent.supersonic.chat.api.pojo.response;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Data
public class AggregateInfo {
private List<MetricInfo> metricInfos = new ArrayList<>();
}

View File

@@ -0,0 +1,26 @@
package com.tencent.supersonic.chat.api.pojo.response;
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeAdvancedConfig;
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
import lombok.Data;
import java.util.List;
@Data
public class ChatAggRichConfigResp {
/**
* invisible dimensions/metrics
*/
private ItemVisibilityInfo visibility;
/**
* information about dictionary about the model
*/
private List<KnowledgeInfoReq> knowledgeInfos;
private KnowledgeAdvancedConfig globalKnowledgeConfig;
private ChatDefaultRichConfigResp chatDefaultConfig;
}

View File

@@ -0,0 +1,35 @@
package com.tencent.supersonic.chat.api.pojo.response;
import com.tencent.supersonic.chat.api.pojo.request.ChatAggConfigReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatDetailConfigReq;
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import java.util.Date;
import java.util.List;
import lombok.Data;
@Data
public class ChatConfigResp {
private Long id;
private Long modelId;
private ChatDetailConfigReq chatDetailConfig;
private ChatAggConfigReq chatAggConfig;
private List<RecommendedQuestionReq> recommendedQuestions;
/**
* available status
*/
private StatusEnum statusEnum;
private String createdBy;
private String updatedBy;
private Date createdAt;
private Date updatedAt;
}

View File

@@ -0,0 +1,35 @@
package com.tencent.supersonic.chat.api.pojo.response;
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import java.util.Date;
import java.util.List;
import lombok.Data;
@Data
public class ChatConfigRichResp {
private Long id;
private Long modelId;
private String modelName;
private String bizName;
private ChatAggRichConfigResp chatAggRichConfig;
private ChatDetailRichConfigResp chatDetailRichConfig;
private List<RecommendedQuestionReq> recommendedQuestions;
/**
* available status
*/
private StatusEnum statusEnum;
private String createdBy;
private String updatedBy;
private Date createdAt;
private Date updatedAt;
}

View File

@@ -0,0 +1,31 @@
package com.tencent.supersonic.chat.api.pojo.response;
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
import com.tencent.supersonic.chat.api.pojo.request.ChatDefaultConfigReq;
import com.tencent.supersonic.common.pojo.Constants;
import lombok.Data;
import java.util.List;
@Data
public class ChatDefaultRichConfigResp {
private List<SchemaElement> dimensions;
private List<SchemaElement> metrics;
/**
* default time span unit
*/
private Integer unit = 1;
/**
* default time type: day
* DAY, WEEK, MONTH, YEAR
*/
private String period = Constants.DAY;
private ChatDefaultConfigReq.TimeMode timeMode;
}

View File

@@ -0,0 +1,27 @@
package com.tencent.supersonic.chat.api.pojo.response;
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeAdvancedConfig;
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
import lombok.Data;
import java.util.List;
@Data
public class ChatDetailRichConfigResp {
/**
* invisible dimensions/metrics
*/
private ItemVisibilityInfo visibility;
/**
* information about dictionary about the model
*/
private List<KnowledgeInfoReq> knowledgeInfos;
private KnowledgeAdvancedConfig globalKnowledgeConfig;
private ChatDefaultRichConfigResp chatDefaultConfig;
}

Some files were not shown because too many files have changed in this diff Show More