mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-13 04:57:28 +00:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8b5c0f3a3 | ||
|
|
ef30e7a5b8 | ||
|
|
12417c66cd | ||
|
|
f00da45824 | ||
|
|
8d8440f724 | ||
|
|
55138986ed | ||
|
|
2c621a1338 | ||
|
|
c6b87d30a5 | ||
|
|
8c5c7c2e32 | ||
|
|
7fce9bacc2 | ||
|
|
8aedfbb6a0 | ||
|
|
eca92d2493 | ||
|
|
a4fc11887c | ||
|
|
e4b0129fba | ||
|
|
76e8d253b1 | ||
|
|
d173924efd | ||
|
|
465416e30c | ||
|
|
a8add4c013 | ||
|
|
02068f58c7 | ||
|
|
3c0edb67c7 | ||
|
|
5bab18e092 | ||
|
|
71d9f9c9e9 | ||
|
|
90f6a20516 | ||
|
|
898108d7e1 | ||
|
|
728e7647dc | ||
|
|
ac0f7ea982 | ||
|
|
20d7941d57 | ||
|
|
ddcdd99188 | ||
|
|
9267f8ed18 | ||
|
|
249728919d | ||
|
|
f3f84ab9af | ||
|
|
90e62ddccc | ||
|
|
fbd145fd92 | ||
|
|
f5a7068d5e | ||
|
|
d5c5c63a75 | ||
|
|
559ef974b0 | ||
|
|
8440f1f30e | ||
|
|
728235907d | ||
|
|
40e0a58502 | ||
|
|
9723c2496e | ||
|
|
4b99736a38 | ||
|
|
36fd737440 | ||
|
|
93ca060c45 | ||
|
|
e1911bc81b | ||
|
|
6fe9ab79ed | ||
|
|
5ee5ab116f | ||
|
|
a6c4d10d70 | ||
|
|
0d65d03bee | ||
|
|
acca5e4538 | ||
|
|
233899ca3e | ||
|
|
aa218898ff | ||
|
|
cf1b5336c3 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,3 +15,4 @@ assembly/runtime/*
|
|||||||
/assembly/deploy
|
/assembly/deploy
|
||||||
/runtime
|
/runtime
|
||||||
**/.flattened-pom.xml
|
**/.flattened-pom.xml
|
||||||
|
__pycache__/
|
||||||
29
CHANGELOG.md
29
CHANGELOG.md
@@ -4,7 +4,36 @@
|
|||||||
- "Breaking Changes" describes any changes that may break existing functionality or cause
|
- "Breaking Changes" describes any changes that may break existing functionality or cause
|
||||||
compatibility issues with previous versions.
|
compatibility issues with previous versions.
|
||||||
|
|
||||||
|
## 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
|
## SuperSonic [0.7.2] - 2023-08-12
|
||||||
|
|
||||||
|
|||||||
48
README.md
48
README.md
@@ -1,4 +1,4 @@
|
|||||||
English | [中文](README_CN.md)
|
[中文介绍](README_CN.md) | [文档中心](https://github.com/tencentmusic/supersonic/wiki)
|
||||||
|
|
||||||
# SuperSonic (超音数)
|
# SuperSonic (超音数)
|
||||||
|
|
||||||
@@ -10,52 +10,54 @@ English | [中文](README_CN.md)
|
|||||||
|
|
||||||
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 queries into SQL queries. While some works show promising results, they are still 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 queries into SQL queries. While some works show promising results, they are still not applicable to real-world scenarios.
|
||||||
|
|
||||||
From our perspective, the key to filling the real-world gap lies in two aspects:
|
From our perspective, the key to filling the real-world gap lies in three aspects:
|
||||||
1. Utilize a combination of rule-based and model-based semantic parsers to deal with different scenarios.
|
1. Complement the LLM-based semantic parser with rule-based semantic parsers to improve **efficiency**(in terms of latency and cost).
|
||||||
2. Introduce a semantic model layer encapsulating the underlying data complexity(joins, formulas, etc) to simplify semantic parsing.
|
2. Augment semantic parsing with schema mappers(as a kind of preprocessor) and semantic correctors(as a kind of postprocessor) to improve **accuracy** and **stability**.
|
||||||
|
3. Introduce a semantic layer encapsulating underlying data context(joins, formulas, etc) to reduce **complexity**.
|
||||||
|
|
||||||
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 data chatbot, we decide 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 data chatbot, we decide to open source SuperSonic as an extensible framework.
|
||||||
|
|
||||||
## Out-of-the-box Features
|
## Out-of-the-box Features
|
||||||
|
|
||||||
- Built-in graphical interface for business users to enter data queries
|
- Built-in CUI(Chat User Interface) for *business users* to enter data queries
|
||||||
- Built-in graphical interface for analytics engineers to manage semantic models
|
- 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 input auto-completion as well as query recommendation
|
||||||
- Support multi-turn conversation and history context management
|
- 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
|
## Extensible Components
|
||||||
|
|
||||||
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="80%" width="80%" align="center"/>
|
<img src="./docs/images/supersonic_components.png" height="65%" width="65%" align="center"/>
|
||||||
|
|
||||||
- **Chat Interface:** accepts natural language queries and answer results with appropriate visualization charts. It supports input auto-completion as well as multi-turn conversation.
|
- **Knowledge Base:** extracts schema information periodically from the semantic models and build dictionary and index to facilitate schema mapping.
|
||||||
|
|
||||||
- **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.
|
- **Schema Mapper:** identifies references to schema elements(metrics/dimensions/entities/values) in user queries. It matches the query text against the knowledge base.
|
||||||
|
|
||||||
- **Schema Mapper Chain:** identifies references to schema elements(metrics/dimensions/entities/values) in user queries. It matches the query text against a knowledge base constructed from the semantic models.
|
- **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.
|
||||||
|
|
||||||
- **Semantic Parser Chain:** understands user queries and extract semantic information. It consists of a combination of rule-based and model-based parsers, each of which deals with specific scenarios.
|
- **Semantic Corrector:** checks validity of extracted semantic information and performs correction and optimization if needed.
|
||||||
|
|
||||||
- **Semantic Query:** performs execution according to extracted semantic information. It generates SQL queries and executes them against physical data models.
|
- **Semantic Layer:** performs execution according to extracted semantic information. It generates SQL queries and executes them against physical data models.
|
||||||
|
|
||||||
|
- **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
|
## 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:
|
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)
|
- 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
|
- Run script "bin/start-standalone.sh" to start services (one java process and one python process)
|
||||||
- Visit http://localhost:9080 in browser to start exploration
|
- Visit http://localhost:9080 in the browser to start exploration
|
||||||
|
|
||||||
## How to Build
|
## Build and Delopment
|
||||||
|
|
||||||
SuperSonic can be deployed in two modes: standalone (intended for quick demo) and distributed (intended for production).
|
Please refer to project [wiki](https://github.com/tencentmusic/supersonic/wiki).
|
||||||
|
|
||||||
### Build for Standalone Mode
|
## WeChat Contact
|
||||||
|
|
||||||
Pull the source code and run script "assembly/bin/build-standalone.sh" to build a single packages.
|
Please join the chat group to suggest feedbacks or ideas:
|
||||||
|
|
||||||
### Build for Distributed Mode
|
<img src="./docs/images/wechat_contact.jpeg" height="40%" width="40%" align="center"/>
|
||||||
|
|
||||||
Pull the source code and run scripts "assembly/bin/build-chat.sh" and "assembly/bin/build-semantic.sh" separately to build packages.
|
|
||||||
42
README_CN.md
42
README_CN.md
@@ -8,52 +8,54 @@
|
|||||||
|
|
||||||
大型语言模型(LLMs)如ChatGPT的出现正在重塑信息检索的方式。在数据分析领域,学术界和工业界主要关注利用深度学习模型将自然语言查询转换为SQL查询。虽然一些工作显示出有前景的结果,但它们还并不适用于实际场景。
|
大型语言模型(LLMs)如ChatGPT的出现正在重塑信息检索的方式。在数据分析领域,学术界和工业界主要关注利用深度学习模型将自然语言查询转换为SQL查询。虽然一些工作显示出有前景的结果,但它们还并不适用于实际场景。
|
||||||
|
|
||||||
在我们看来,为了在实际场景发挥价值,有两个关键点:
|
在我们看来,为了在实际场景发挥价值,有三个关键点:
|
||||||
1. 将基于规则和基于模型的语义解析器相结合,发挥各自优势,以便处理不同的场景。
|
1. 在基于大模型语义解析器基础上,增加基于规则的解析器,提升语义解析的**效率**。
|
||||||
2. 引入语义模型层来封装数据底层的复杂性(关联、公式等),从而简化语义解析的求解空间。
|
2. 加入模式映射器和语义修正器,来增强语义解析能力,提升语义解析的**准确性**和**稳定性**。
|
||||||
|
3. 引入语义模型层,封装底层数据的上下文(关联、公式等),降低语义解析的**复杂性**。
|
||||||
|
|
||||||
为了验证上述想法,我们开发了超音数项目,并将其应用在实际的内部产品中。与此同时,我们将超音数作为一个可扩展的框架开源,希望能够促进数据问答对话领域的进一步发展。
|
为了验证上述想法,我们开发了超音数项目,并将其应用在实际的内部产品中。与此同时,我们将超音数作为一个可扩展的框架开源,希望能够促进数据问答对话领域的进一步发展。
|
||||||
|
|
||||||
## 开箱即用的特性
|
## 开箱即用的特性
|
||||||
|
|
||||||
- 内置图形界面以便业务用户输入数据查询。
|
- 内置对话界面以便*业务用户*输入数据查询。
|
||||||
- 内置图形界面以便分析工程师管理语义模型。
|
- 内置图形界面以便*分析工程师*构建语义模型。
|
||||||
|
- 内置图形界面以便*系统管理员*管理第三方插件和对话助理。
|
||||||
- 支持文本输入的联想和查询问题的推荐。
|
- 支持文本输入的联想和查询问题的推荐。
|
||||||
- 支持多轮对话,根据语境自动切换上下文。
|
- 支持多轮对话,根据语境自动切换上下文。
|
||||||
- 支持三级权限控制:主题域级、列级、行级。
|
- 支持四级权限控制:主题域级、模型级、列级、行级。
|
||||||
|
|
||||||
## 易于扩展的组件
|
## 易于扩展的组件
|
||||||
|
|
||||||
超音数的整体架构和主流程如下图所示:
|
超音数的整体架构和主流程如下图所示:
|
||||||
|
|
||||||
<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"/>
|
||||||
|
|
||||||
- **问答对话界面(chat interface)**:接受用户查询并选择合适的可视化图表呈现结果,支持输入联想和多轮对话。
|
- **知识库(Knowledge Base):** 定期从语义模型中提取相关的模式信息,构建词典和索引,以便后续的模式映射。
|
||||||
|
|
||||||
- **语义建模界面(modeling interface)**:使分析工程师能够通过可视化方式定义和维护语义模型,与访问权限和聊天对话相关的配置也可以在用户界面上设置。
|
- **模式映射器(Schema Mapper):** 将自然语言文本在知识库中进行匹配,为后续的语义解析提供相关信息。
|
||||||
|
|
||||||
- **模式映射器(schema mapper chain)**:基于语义模型构建知识库,然后将自然语言文本在知识库中进行匹配,为后续的语义解析提供相关信息。
|
- **语义解析器(Semantic Parser):** 理解用户查询并抽取语义信息,其由一组基于规则和基于模型的解析器组成,每个解析器可应对不同的特定场景。
|
||||||
|
|
||||||
- **语义解析器(semantic parser chain)**:理解用户查询并抽取语义信息,其由一组基于规则和基于模型的解析器组成,每个解析器可应对不同的特定场景。
|
- **语义修正器(Semantic Corrector):** 检查语义信息的合法性,对不合法的信息做修正和优化处理。
|
||||||
|
|
||||||
- **语义查询(semantic query)**: 根据语义信息生成物理SQL执行查询。
|
- **语义模型层(Semantic Layer):** 根据语义信息生成物理SQL执行查询。
|
||||||
|
|
||||||
|
- **问答插件(Chat Plugin):** 通过第三方工具扩展功能。给定所有配置的插件及其功能描述和示例问题,大语言模型将选择最合适的插件。
|
||||||
|
|
||||||
## 快速体验
|
## 快速体验
|
||||||
|
|
||||||
超音数自带样例的语义模型和问答对话,只需以下三步即可快速体验:
|
超音数自带样例的语义模型和问答对话,只需以下三步即可快速体验:
|
||||||
|
|
||||||
- 从[release page](https://github.com/tencentmusic/supersonic/releases)下载预先构建好的发行包
|
- 从[release page](https://github.com/tencentmusic/supersonic/releases)下载预先构建好的发行包
|
||||||
- 运行 "bin/start-standalone.sh"启动服务
|
- 运行 "bin/start-standalone.sh"启动服务(一个Java进程和一个Python进程)
|
||||||
- 在浏览器访问http://localhost:9080 开启探索
|
- 在浏览器访问http://localhost:9080 开启探索
|
||||||
|
|
||||||
## 如何构建
|
## 如何构建和部署
|
||||||
|
|
||||||
超音数可以运行在两个模式:standalone(一般用于快速演示)和distributed(一般用于生产环境)。
|
请参考项目[wiki](https://github.com/tencentmusic/supersonic/wiki)。
|
||||||
|
|
||||||
### Standalone模式构建
|
## 微信联系方式
|
||||||
|
|
||||||
下载源码包,运行脚本"assembly/bin/build-standalone.sh",将所有服务一起编译打包
|
欢迎加入微信群反馈建议:
|
||||||
|
|
||||||
### Distributed模式构建
|
<img src="./docs/images/wechat_contact.jpeg" height="40%" width="40%" align="center"/>
|
||||||
|
|
||||||
下载源码包,分别运行脚本"assembly/bin/build-chat.sh"、"assembly/bin/build-semantic.sh",为问答层服务和语义层服务编译打包
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
sbinDir=$(cd "$(dirname "$0")"; pwd)
|
|
||||||
baseDir=$(readlink -f $sbinDir/../)
|
|
||||||
buildDir=$baseDir/build
|
|
||||||
|
|
||||||
cd $baseDir/bin
|
|
||||||
sh build-standalone.sh
|
|
||||||
|
|
||||||
cd $buildDir
|
|
||||||
tar xvf supersonic-webapp.tar.gz
|
|
||||||
mv supersonic-webapp webapp
|
|
||||||
mv webapp ../../launchers/standalone/target/classes
|
|
||||||
@@ -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}/
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
30
assembly/bin/supersonic-build.bat
Normal file
30
assembly/bin/supersonic-build.bat
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
|
||||||
|
set "sbinDir=%~dp0"
|
||||||
|
set "baseDir=%~dp0.."
|
||||||
|
set "buildDir=%baseDir%\build"
|
||||||
|
|
||||||
|
|
||||||
|
rem 1. build semantic chat service
|
||||||
|
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"
|
||||||
|
echo f|xcopy "%baseDir%\..\launchers\semantic\target\*.tar.gz" "%buildDir%\supersonic-semantic.tar.gz"
|
||||||
|
echo f|xcopy "%baseDir%\..\launchers\chat\target\*.tar.gz" "%buildDir%\supersonic-chat.tar.gz"
|
||||||
|
|
||||||
|
rem 3. build webapp
|
||||||
|
cd "%baseDir%\..\webapp"
|
||||||
|
call start-fe-prod.bat
|
||||||
|
copy /y "%baseDir%\..\webapp\supersonic-webapp.tar.gz" "%buildDir%\"
|
||||||
|
|
||||||
|
|
||||||
|
cd "%buildDir%"
|
||||||
|
tar -zxvf supersonic-webapp.tar.gz
|
||||||
|
move supersonic-webapp webapp
|
||||||
|
move webapp ..\..\launchers\standalone\target\classes
|
||||||
|
|
||||||
|
endlocal
|
||||||
8
assembly/bin/build-standalone.sh → assembly/bin/supersonic-build.sh
Executable file → Normal file
8
assembly/bin/build-standalone.sh → assembly/bin/supersonic-build.sh
Executable file → Normal file
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
sbinDir=$(cd "$(dirname "$0")"; pwd)
|
sbinDir=$(cd "$(dirname "$0")"; pwd)
|
||||||
baseDir=$(readlink -f $sbinDir/../)
|
baseDir=$(cd "$sbinDir/.." && pwd -P)
|
||||||
runtimeDir=$baseDir/runtime
|
runtimeDir=$baseDir/runtime
|
||||||
buildDir=$baseDir/build
|
buildDir=$baseDir/build
|
||||||
|
|
||||||
@@ -21,3 +21,9 @@ chmod +x $baseDir/../webapp/start-fe-prod.sh
|
|||||||
cd ../webapp
|
cd ../webapp
|
||||||
sh ./start-fe-prod.sh
|
sh ./start-fe-prod.sh
|
||||||
cp -fr ./supersonic-webapp.tar.gz ${buildDir}/
|
cp -fr ./supersonic-webapp.tar.gz ${buildDir}/
|
||||||
|
|
||||||
|
|
||||||
|
cd $buildDir
|
||||||
|
tar xvf supersonic-webapp.tar.gz
|
||||||
|
mv supersonic-webapp webapp
|
||||||
|
mv webapp ../../launchers/standalone/target/classes
|
||||||
120
assembly/bin/supersonic-daemon.bat
Normal file
120
assembly/bin/supersonic-daemon.bat
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
|
||||||
|
set "sbinDir=%~dp0"
|
||||||
|
set "baseDir=%~dp0.."
|
||||||
|
set "runtimeDir=%baseDir%\..\runtime"
|
||||||
|
set "buildDir=%baseDir%\build"
|
||||||
|
|
||||||
|
set "command=%~1"
|
||||||
|
set "module=%~2"
|
||||||
|
|
||||||
|
set "APP_NAME=standalone-service"
|
||||||
|
set "MAIN_CLASS=com.tencent.supersonic.StandaloneLauncher"
|
||||||
|
|
||||||
|
set "python_path=python"
|
||||||
|
set "pip_path=pip3.9"
|
||||||
|
set "llm_host=127.0.0.1"
|
||||||
|
set "llm_port=9092"
|
||||||
|
set "start_name=api_service"
|
||||||
|
|
||||||
|
set "llm_path=%baseDir%\..\chat\core\src\main\python"
|
||||||
|
|
||||||
|
if "%module%"=="" (
|
||||||
|
set "module=standalone"
|
||||||
|
) else if "%module%"=="semantic" (
|
||||||
|
set "APP_NAME=semantic-service"
|
||||||
|
set "MAIN_CLASS=com.tencent.supersonic.SemanticLauncher"
|
||||||
|
) else if "%module%"=="chat" (
|
||||||
|
set "APP_NAME=chat-service"
|
||||||
|
set "MAIN_CLASS=com.tencent.supersonic.ChatLauncher"
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%command%"=="" (
|
||||||
|
set "command=restart"
|
||||||
|
)
|
||||||
|
|
||||||
|
set "libDir=%runtimeDir%\supersonic-%module%\lib"
|
||||||
|
set "confDir=%runtimeDir%\supersonic-%module%\conf"
|
||||||
|
set "webDir=%runtimeDir%\supersonic-%module%\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%"
|
||||||
|
|
||||||
|
|
||||||
|
if "%command%"=="stop" (
|
||||||
|
call:STOP
|
||||||
|
goto :EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%command%"=="restart" (
|
||||||
|
call:STOP
|
||||||
|
)
|
||||||
|
|
||||||
|
::1. clear file
|
||||||
|
rd /s /q "%runtimeDir%"
|
||||||
|
mkdir "%runtimeDir%"
|
||||||
|
|
||||||
|
if "%module%"=="llmparser" (
|
||||||
|
tar -zxvf "%buildDir%\supersonic-standalone.tar.gz" -C "%runtimeDir%"
|
||||||
|
for /d %%f in ("%runtimeDir%\launchers-standalone-*") do (
|
||||||
|
move "%%f" "%runtimeDir%\supersonic-standalone"
|
||||||
|
)
|
||||||
|
cd "%runtimeDir%"
|
||||||
|
"%pip_path%" install -r "%llm_path%\requirements.txt"
|
||||||
|
"%python_path%" -c "import langchain,fastapi,chromadb,tiktoken,uvicorn" >nul 2>&1
|
||||||
|
cd "%runtimeDir%\supersonic-standalone\llm\llm"
|
||||||
|
start "" /B uvicorn %start_name%:app --port %llm_port% --host %llm_host% > "%runtimeDir%\supersonic-standalone\llm\llm.log" 2>&1
|
||||||
|
echo "llm service started, see logs/error with logs/error command"
|
||||||
|
goto :EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
tar -zxvf "%buildDir%\supersonic-%module%.tar.gz" -C "%runtimeDir%"
|
||||||
|
for /d %%f in ("%runtimeDir%\launchers-%module%-*") do (
|
||||||
|
move "%%f" "%runtimeDir%\supersonic-%module%"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not exist "%runtimeDir%\supersonic-%module%\logs" mkdir "%runtimeDir%\supersonic-%module%\logs"
|
||||||
|
|
||||||
|
tar -zxvf "%buildDir%\supersonic-webapp.tar.gz" -C "%buildDir%"
|
||||||
|
if not exist "%runtimeDir%\supersonic-%module%\webapp" mkdir "%runtimeDir%\supersonic-%module%\webapp"
|
||||||
|
xcopy /s /e /h /y "%buildDir%\supersonic-webapp\*" "%runtimeDir%\supersonic-%module%\webapp"
|
||||||
|
if not exist "%runtimeDir%\supersonic-%module%\conf\webapp" mkdir "%runtimeDir%\supersonic-%module%\conf\webapp"
|
||||||
|
xcopy /s /e /h /y "%runtimeDir%\supersonic-%module%\webapp\*" "%runtimeDir%\supersonic-%module%\conf\webapp"
|
||||||
|
rd /s /q "%buildDir%\supersonic-webapp"
|
||||||
|
|
||||||
|
::3. start service
|
||||||
|
::start standalone service
|
||||||
|
if "%command%"=="start" (
|
||||||
|
call:START
|
||||||
|
goto :EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%command%"=="restart" (
|
||||||
|
call:START
|
||||||
|
goto :EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
:START
|
||||||
|
if "%module%"=="standalone" (
|
||||||
|
cd "%runtimeDir%"
|
||||||
|
"%pip_path%" install -r "%llm_path%\requirements.txt"
|
||||||
|
"%python_path%" -c "import langchain,fastapi,chromadb,tiktoken,uvicorn" >nul 2>&1
|
||||||
|
cd "%runtimeDir%\supersonic-standalone\llm\llm"
|
||||||
|
start "" /B uvicorn %start_name%:app --port %llm_port% --host %llm_host% > "%runtimeDir%\supersonic-standalone\llm\llm.log" 2>&1
|
||||||
|
echo "llm service started, see logs/error with logs/error command"
|
||||||
|
)
|
||||||
|
start "supersonic" /B java %java-command%>"%runtimeDir%\supersonic-%module%\logs\info-%module%.log" 2>&1
|
||||||
|
echo "%module% service started, see logs/error with logs/error command"
|
||||||
|
goto :EOF
|
||||||
|
|
||||||
|
|
||||||
|
:STOP
|
||||||
|
for /f "tokens=2" %%i in ('tasklist ^| findstr /i "python"') do (
|
||||||
|
taskkill /PID %%i /F
|
||||||
|
echo "llm Process (PID = %%i) is killed."
|
||||||
|
)
|
||||||
|
for /f "tokens=2" %%i in ('tasklist ^| findstr /i "java"') do (
|
||||||
|
taskkill /PID %%i /F
|
||||||
|
echo "%module% Process (PID = %%i) is killed."
|
||||||
|
)
|
||||||
|
goto :EOF
|
||||||
98
assembly/bin/supersonic-daemon.sh
Normal file
98
assembly/bin/supersonic-daemon.sh
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
sbinDir=$(cd "$(dirname "$0")"; pwd)
|
||||||
|
baseDir=$(cd "$sbinDir/.." && pwd -P)
|
||||||
|
runtimeDir=$baseDir/../runtime
|
||||||
|
buildDir=$baseDir/build
|
||||||
|
|
||||||
|
command=$1
|
||||||
|
service=$2
|
||||||
|
|
||||||
|
cd $baseDir
|
||||||
|
if [[ "$service" == "semantic" || -z "$service" ]] && [ "$command" != "stop" ]; then
|
||||||
|
#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
|
||||||
|
fi
|
||||||
|
if [[ "$service" == "semantic" ]]; then
|
||||||
|
json=$(cat ${runtimeDir}/supersonic-semantic/webapp/supersonic.config.json)
|
||||||
|
json=$(echo $json | jq '.env="semantic"')
|
||||||
|
echo $json > ${runtimeDir}/supersonic-semantic/webapp/supersonic.config.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$service" == "chat" ]]; then
|
||||||
|
json=$(cat ${runtimeDir}/supersonic-chat/webapp/supersonic.config.json)
|
||||||
|
json=$(echo $json | jq '.env="chat"')
|
||||||
|
echo $json > ${runtimeDir}/supersonic-chat/webapp/supersonic.config.json
|
||||||
|
fi
|
||||||
|
echo $command
|
||||||
|
echo $service
|
||||||
|
case "$command" in
|
||||||
|
start)
|
||||||
|
if [[ "$service" == "semantic" ]];then
|
||||||
|
echo -e "Starting semantic"
|
||||||
|
sh ${runtimeDir}/supersonic-semantic/bin/service.sh start
|
||||||
|
elif [[ "$service" == "chat" ]];then
|
||||||
|
echo -e "Starting chat"
|
||||||
|
sh ${runtimeDir}/supersonic-chat/bin/service.sh start
|
||||||
|
elif [[ "$service" == "llmparser" ]];then
|
||||||
|
echo -e "Starting LLM"
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh start
|
||||||
|
elif [[ -z "$service" ]]; then
|
||||||
|
echo -e "Starting supersonic"
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/bin/service.sh start
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh start
|
||||||
|
else
|
||||||
|
echo "Use command {semantic|semantic||} to run."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
if [[ "$service" == "semantic" ]];then
|
||||||
|
echo -e "Stopping semantic"
|
||||||
|
sh ${runtimeDir}/supersonic-semantic/bin/service.sh stop
|
||||||
|
elif [[ "$service" == "chat" ]];then
|
||||||
|
echo -e "Stopping chat"
|
||||||
|
sh ${runtimeDir}/supersonic-chat/bin/service.sh stop
|
||||||
|
elif [[ "$service" == "llmparser" ]];then
|
||||||
|
echo -e "Stopping LLM"
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh stop
|
||||||
|
elif [[ -z "$service" ]]; then
|
||||||
|
echo -e "Stopping supersonic"
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/bin/service.sh stop
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh stop
|
||||||
|
else
|
||||||
|
echo "Use command {semantic|semantic||} to run."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
if [[ "$service" == "semantic" ]];then
|
||||||
|
echo -e "Restarting semantic"
|
||||||
|
sh ${runtimeDir}/supersonic-semantic/bin/service.sh restart
|
||||||
|
elif [[ "$service" == "chat" ]];then
|
||||||
|
echo -e "Restarting chat"
|
||||||
|
sh ${runtimeDir}/supersonic-chat/bin/service.sh restart
|
||||||
|
elif [[ "$service" == "llmparser" ]];then
|
||||||
|
echo -e "Restarting LLM"
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh restart
|
||||||
|
elif [[ -z "$service" ]]; then
|
||||||
|
echo -e "Restarting supersonic"
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/bin/service.sh restart
|
||||||
|
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh restart
|
||||||
|
else
|
||||||
|
echo "Use command {semantic|semantic||} to run."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Use command {start|stop|status|restart} to run."
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -3,6 +3,7 @@ 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.Organization;
|
||||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
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.request.UserReq;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,19 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class AuthenticationConfig {
|
public class AuthenticationConfig {
|
||||||
|
|
||||||
|
|
||||||
@Value("${authentication.exclude.path:XXX}")
|
@Value("${authentication.exclude.path:XXX}")
|
||||||
private String excludePath;
|
private String excludePath;
|
||||||
|
|
||||||
|
@Value("${authentication.include.path:/api}")
|
||||||
|
private String includePath;
|
||||||
|
|
||||||
@Value("${authentication.enable:false}")
|
@Value("${authentication.enable:false}")
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
@Value("${authentication.token.secret:secret}")
|
@Value("${authentication.token.secret:secret}")
|
||||||
private String tokenSecret;
|
private String tokenSecret;
|
||||||
|
|
||||||
@Value("${authentication.token.http.header.key:Auth}")
|
@Value("${authentication.token.http.header.key:Authorization}")
|
||||||
private String tokenHttpHeaderKey;
|
private String tokenHttpHeaderKey;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package com.tencent.supersonic.auth.api.authentication.pojo;
|
package com.tencent.supersonic.auth.api.authentication.pojo;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class Organization {
|
public class Organization {
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ 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.Organization;
|
||||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
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.request.UserReq;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.tencent.supersonic.auth.api.authentication.service;
|
package com.tencent.supersonic.auth.api.authentication.service;
|
||||||
|
|
||||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.tencent.supersonic.auth.api.authorization.request;
|
|||||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes;
|
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
@@ -10,8 +11,6 @@ import lombok.ToString;
|
|||||||
@ToString
|
@ToString
|
||||||
public class QueryAuthResReq {
|
public class QueryAuthResReq {
|
||||||
|
|
||||||
private String user;
|
|
||||||
|
|
||||||
private List<String> departmentIds = new ArrayList<>();
|
private List<String> departmentIds = new ArrayList<>();
|
||||||
|
|
||||||
private List<AuthRes> resources;
|
private List<AuthRes> resources;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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.pojo.DimensionFilter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.tencent.supersonic.auth.api.authorization.service;
|
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.pojo.AuthGroup;
|
||||||
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
|
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.response.AuthorizedResourceResp;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
public interface AuthService {
|
public interface AuthService {
|
||||||
|
|
||||||
@@ -14,5 +14,5 @@ public interface AuthService {
|
|||||||
|
|
||||||
void removeAuthGroup(AuthGroup group);
|
void removeAuthGroup(AuthGroup group);
|
||||||
|
|
||||||
AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, HttpServletRequest request);
|
AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, User user);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
|
|||||||
import com.tencent.supersonic.auth.authentication.persistence.repository.UserRepository;
|
import com.tencent.supersonic.auth.authentication.persistence.repository.UserRepository;
|
||||||
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
||||||
import com.tencent.supersonic.common.util.ContextUtils;
|
import com.tencent.supersonic.common.util.ContextUtils;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
|
|
||||||
public class DefaultUserAdaptor implements UserAdaptor {
|
public class DefaultUserAdaptor implements UserAdaptor {
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package com.tencent.supersonic.auth.authentication.config;
|
|
||||||
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Configuration
|
|
||||||
public class TppConfig {
|
|
||||||
|
|
||||||
@Value(value = "${auth.app.secret:}")
|
|
||||||
private String appSecret;
|
|
||||||
|
|
||||||
@Value(value = "${auth.app.key:}")
|
|
||||||
private String appKey;
|
|
||||||
|
|
||||||
@Value(value = "${auth.oa.url:}")
|
|
||||||
private String tppOaUrl;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -42,6 +42,17 @@ public abstract class AuthenticationInterceptor implements HandlerInterceptor {
|
|||||||
return excludePaths.stream().anyMatch(uri::startsWith);
|
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) {
|
protected boolean isInternalRequest(HttpServletRequest request) {
|
||||||
String internal = request.getHeader(UserConstants.INTERNAL);
|
String internal = request.getHeader(UserConstants.INTERNAL);
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
|
|||||||
}
|
}
|
||||||
|
|
||||||
String uri = request.getServletPath();
|
String uri = request.getServletPath();
|
||||||
|
if (!isIncludedUri(uri)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (isExcludedUri(uri)) {
|
if (isExcludedUri(uri)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package com.tencent.supersonic.auth.authentication.interceptor;
|
package com.tencent.supersonic.auth.authentication.interceptor;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class InterceptorFactory implements WebMvcConfigurer {
|
public class InterceptorFactory implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.tencent.supersonic.auth.authentication.persistence.repository.Impl;
|
package com.tencent.supersonic.auth.authentication.persistence.repository.impl;
|
||||||
|
|
||||||
|
|
||||||
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
|
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.dataobject.UserDOExample;
|
||||||
import com.tencent.supersonic.auth.authentication.persistence.mapper.UserDOMapper;
|
|
||||||
import com.tencent.supersonic.auth.authentication.persistence.repository.UserRepository;
|
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.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import java.util.Set;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/auth/user")
|
@RequestMapping("/api/auth/user")
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.tencent.supersonic.auth.api.authentication.service.UserService;
|
|||||||
import com.tencent.supersonic.auth.authentication.utils.ComponentFactory;
|
import com.tencent.supersonic.auth.authentication.utils.ComponentFactory;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.tencent.supersonic.auth.authentication.utils;
|
package com.tencent.supersonic.auth.authentication.utils;
|
||||||
|
|
||||||
import com.tencent.supersonic.auth.api.authentication.adaptor.UserAdaptor;
|
import com.tencent.supersonic.auth.api.authentication.adaptor.UserAdaptor;
|
||||||
import java.util.Objects;
|
|
||||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ComponentFactory {
|
public class ComponentFactory {
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ 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_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_NAME;
|
||||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_PASSWORD;
|
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.config.AuthenticationConfig;
|
||||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
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.pojo.UserWithPassword;
|
||||||
@@ -22,9 +21,11 @@ import java.util.Date;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class UserTokenUtils {
|
public class UserTokenUtils {
|
||||||
|
|
||||||
@@ -68,7 +69,9 @@ public class UserTokenUtils {
|
|||||||
public UserWithPassword getUserWithPassword(HttpServletRequest request) {
|
public UserWithPassword getUserWithPassword(HttpServletRequest request) {
|
||||||
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
|
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
|
||||||
if (StringUtils.isBlank(token)) {
|
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);
|
final Claims claims = getClaims(token);
|
||||||
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
|
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="com.tencent.supersonic.auth.authentication.persistence.mapper.UserDOMapper">
|
<mapper namespace="com.tencent.supersonic.auth.authentication.persistence.mapper.UserDOMapper">
|
||||||
<resultMap id="BaseResultMap"
|
<resultMap id="BaseResultMap" type="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
||||||
type="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
|
||||||
<id column="id" jdbcType="BIGINT" property="id" />
|
<id column="id" jdbcType="BIGINT" property="id" />
|
||||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||||
<result column="password" jdbcType="VARCHAR" property="password" />
|
<result column="password" jdbcType="VARCHAR" property="password" />
|
||||||
@@ -24,13 +22,11 @@
|
|||||||
and ${criterion.condition} #{criterion.value}
|
and ${criterion.condition} #{criterion.value}
|
||||||
</when>
|
</when>
|
||||||
<when test="criterion.betweenValue">
|
<when test="criterion.betweenValue">
|
||||||
and ${criterion.condition} #{criterion.value} and
|
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||||
#{criterion.secondValue}
|
|
||||||
</when>
|
</when>
|
||||||
<when test="criterion.listValue">
|
<when test="criterion.listValue">
|
||||||
and ${criterion.condition}
|
and ${criterion.condition}
|
||||||
<foreach close=")" collection="criterion.value" item="listItem"
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||||
open="(" separator=",">
|
|
||||||
#{listItem}
|
#{listItem}
|
||||||
</foreach>
|
</foreach>
|
||||||
</when>
|
</when>
|
||||||
@@ -42,12 +38,9 @@
|
|||||||
</where>
|
</where>
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id
|
id, name, password, display_name, email
|
||||||
, name, password, display_name, email
|
|
||||||
</sql>
|
</sql>
|
||||||
<select id="selectByExample"
|
<select id="selectByExample" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample" resultMap="BaseResultMap">
|
||||||
parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample"
|
|
||||||
resultMap="BaseResultMap">
|
|
||||||
select
|
select
|
||||||
<if test="distinct">
|
<if test="distinct">
|
||||||
distinct
|
distinct
|
||||||
@@ -71,19 +64,16 @@
|
|||||||
where id = #{id,jdbcType=BIGINT}
|
where id = #{id,jdbcType=BIGINT}
|
||||||
</select>
|
</select>
|
||||||
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
|
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
|
||||||
delete
|
delete from s2_user
|
||||||
from s2_user
|
|
||||||
where id = #{id,jdbcType=BIGINT}
|
where id = #{id,jdbcType=BIGINT}
|
||||||
</delete>
|
</delete>
|
||||||
<insert id="insert"
|
<insert id="insert" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
||||||
parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
|
||||||
insert into s2_user (id, name, password,
|
insert into s2_user (id, name, password,
|
||||||
display_name, email)
|
display_name, email)
|
||||||
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
|
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
|
||||||
#{displayName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR})
|
#{displayName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR})
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective"
|
<insert id="insertSelective" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
||||||
parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
|
||||||
insert into s2_user
|
insert into s2_user
|
||||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
<if test="id != null">
|
<if test="id != null">
|
||||||
@@ -120,16 +110,13 @@
|
|||||||
</if>
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
<select id="countByExample"
|
<select id="countByExample" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample" resultType="java.lang.Long">
|
||||||
parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample"
|
|
||||||
resultType="java.lang.Long">
|
|
||||||
select count(*) from s2_user
|
select count(*) from s2_user
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Example_Where_Clause" />
|
<include refid="Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
<update id="updateByPrimaryKeySelective"
|
<update id="updateByPrimaryKeySelective" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
||||||
parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
|
||||||
update s2_user
|
update s2_user
|
||||||
<set>
|
<set>
|
||||||
<if test="name != null">
|
<if test="name != null">
|
||||||
@@ -147,8 +134,7 @@
|
|||||||
</set>
|
</set>
|
||||||
where id = #{id,jdbcType=BIGINT}
|
where id = #{id,jdbcType=BIGINT}
|
||||||
</update>
|
</update>
|
||||||
<update id="updateByPrimaryKey"
|
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
||||||
parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
|
||||||
update s2_user
|
update s2_user
|
||||||
set name = #{name,jdbcType=VARCHAR},
|
set name = #{name,jdbcType=VARCHAR},
|
||||||
password = #{password,jdbcType=VARCHAR},
|
password = #{password,jdbcType=VARCHAR},
|
||||||
|
|||||||
@@ -35,10 +35,6 @@
|
|||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.tencent.supersonic</groupId>
|
<groupId>com.tencent.supersonic</groupId>
|
||||||
<artifactId>auth-authentication</artifactId>
|
<artifactId>auth-authentication</artifactId>
|
||||||
|
|||||||
@@ -2,27 +2,27 @@ package com.tencent.supersonic.auth.authorization.application;
|
|||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.gson.Gson;
|
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.authentication.service.UserService;
|
||||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthGroup;
|
|
||||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes;
|
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.AuthResGrp;
|
||||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRule;
|
|
||||||
import com.tencent.supersonic.auth.api.authorization.pojo.DimensionFilter;
|
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.request.QueryAuthResReq;
|
||||||
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
|
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.service.AuthService;
|
||||||
import java.util.ArrayList;
|
import com.tencent.supersonic.auth.api.authorization.pojo.AuthGroup;
|
||||||
import java.util.List;
|
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRule;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -78,12 +78,12 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, HttpServletRequest request) {
|
public AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, User user) {
|
||||||
Set<String> userOrgIds = userService.getUserAllOrgId(req.getUser());
|
Set<String> userOrgIds = userService.getUserAllOrgId(user.getName());
|
||||||
if (!CollectionUtils.isEmpty(userOrgIds)) {
|
if (!CollectionUtils.isEmpty(userOrgIds)) {
|
||||||
req.setDepartmentIds(new ArrayList<>(userOrgIds));
|
req.setDepartmentIds(new ArrayList<>(userOrgIds));
|
||||||
}
|
}
|
||||||
List<AuthGroup> groups = getAuthGroups(req);
|
List<AuthGroup> groups = getAuthGroups(req, user.getName());
|
||||||
AuthorizedResourceResp resource = new AuthorizedResourceResp();
|
AuthorizedResourceResp resource = new AuthorizedResourceResp();
|
||||||
Map<String, List<AuthGroup>> authGroupsByModelId = groups.stream()
|
Map<String, List<AuthGroup>> authGroupsByModelId = groups.stream()
|
||||||
.collect(Collectors.groupingBy(AuthGroup::getModelId));
|
.collect(Collectors.groupingBy(AuthGroup::getModelId));
|
||||||
@@ -130,14 +130,14 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AuthGroup> getAuthGroups(QueryAuthResReq req) {
|
private List<AuthGroup> getAuthGroups(QueryAuthResReq req, String userName) {
|
||||||
List<AuthGroup> groups = load().stream()
|
List<AuthGroup> groups = load().stream()
|
||||||
.filter(group -> {
|
.filter(group -> {
|
||||||
if (!Objects.equals(group.getModelId(), req.getModelId())) {
|
if (!Objects.equals(group.getModelId(), req.getModelId())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!CollectionUtils.isEmpty(group.getAuthorizedUsers()) && group.getAuthorizedUsers()
|
if (!CollectionUtils.isEmpty(group.getAuthorizedUsers()) && group.getAuthorizedUsers()
|
||||||
.contains(req.getUser())) {
|
.contains(userName)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (String departmentId : req.getDepartmentIds()) {
|
for (String departmentId : req.getDepartmentIds()) {
|
||||||
@@ -148,7 +148,7 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
log.info("user:{} department:{} authGroups:{}", req.getUser(), req.getDepartmentIds(), groups);
|
log.info("user:{} department:{} authGroups:{}", userName, req.getDepartmentIds(), groups);
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package com.tencent.supersonic.auth.authorization.rest;
|
package com.tencent.supersonic.auth.authorization.rest;
|
||||||
|
|
||||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthGroup;
|
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.request.QueryAuthResReq;
|
||||||
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
|
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.service.AuthService;
|
||||||
|
import com.tencent.supersonic.auth.api.authorization.pojo.AuthGroup;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -62,12 +65,13 @@ public class AuthController {
|
|||||||
* 查询有权限访问的受限资源id
|
* 查询有权限访问的受限资源id
|
||||||
*
|
*
|
||||||
* @param req
|
* @param req
|
||||||
* @param request
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@PostMapping("/queryAuthorizedRes")
|
@PostMapping("/queryAuthorizedRes")
|
||||||
public AuthorizedResourceResp queryAuthorizedResources(@RequestBody QueryAuthResReq req,
|
public AuthorizedResourceResp queryAuthorizedResources(@RequestBody QueryAuthResReq req,
|
||||||
HttpServletRequest request) {
|
HttpServletRequest request,
|
||||||
return authService.queryAuthorizedResources(req, request);
|
HttpServletResponse response) {
|
||||||
|
User user = UserHolder.findUser(request, response);
|
||||||
|
return authService.queryAuthorizedResources(req, user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,8 @@ package com.tencent.supersonic.chat.api.component;
|
|||||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines the contract for a schema mapper that identifies references to schema
|
* A schema mapper identifies references to schema elements(metrics/dimensions/entities/values)
|
||||||
* elements in natural language queries.
|
* in user queries. It matches the query text against the knowledge base.
|
||||||
*
|
|
||||||
* The schema mapper matches queries against the knowledge base which is constructed using the
|
|
||||||
* schema of semantic models.
|
|
||||||
*/
|
*/
|
||||||
public interface SchemaMapper {
|
public interface SchemaMapper {
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -6,21 +6,21 @@ import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
|||||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
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.PageDimensionReq;
|
||||||
import com.tencent.supersonic.semantic.api.model.request.PageMetricReq;
|
import com.tencent.supersonic.semantic.api.model.request.PageMetricReq;
|
||||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
|
||||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
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.model.response.QueryResultWithSchemaResp;
|
||||||
import com.tencent.supersonic.semantic.api.query.request.QueryDslReq;
|
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.QueryMultiStructReq;
|
||||||
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines the contract for a semantic layer that provides a simplified and
|
* A semantic layer provides a simplified and consistent view of data from multiple sources.
|
||||||
* consistent view of data from multiple sources.
|
* It abstracts away the complexity of the underlying data sources and provides a unified view
|
||||||
* The semantic layer abstracts away the complexity of the underlying data sources and provides
|
* of the data that is easier to understand and use.
|
||||||
* a unified view of the data that is easier to understand and use.
|
|
||||||
* <p>
|
* <p>
|
||||||
* The interface defines methods for getting metadata as well as querying data in the semantic layer.
|
* 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
|
* Implementations of this interface should provide concrete implementations that interact with the
|
||||||
@@ -31,22 +31,13 @@ import java.util.List;
|
|||||||
public interface SemanticLayer {
|
public interface SemanticLayer {
|
||||||
|
|
||||||
QueryResultWithSchemaResp queryByStruct(QueryStructReq queryStructReq, User user);
|
QueryResultWithSchemaResp queryByStruct(QueryStructReq queryStructReq, User user);
|
||||||
|
|
||||||
QueryResultWithSchemaResp queryByMultiStruct(QueryMultiStructReq queryMultiStructReq, User user);
|
QueryResultWithSchemaResp queryByMultiStruct(QueryMultiStructReq queryMultiStructReq, User user);
|
||||||
|
|
||||||
QueryResultWithSchemaResp queryByDsl(QueryDslReq queryDslReq, User user);
|
QueryResultWithSchemaResp queryByDsl(QueryDslReq queryDslReq, User user);
|
||||||
|
|
||||||
List<ModelSchema> getModelSchema();
|
List<ModelSchema> getModelSchema();
|
||||||
|
|
||||||
List<ModelSchema> getModelSchema(List<Long> ids);
|
List<ModelSchema> getModelSchema(List<Long> ids);
|
||||||
|
|
||||||
ModelSchema getModelSchema(Long model, Boolean cacheEnable);
|
ModelSchema getModelSchema(Long model, Boolean cacheEnable);
|
||||||
|
|
||||||
PageInfo<DimensionResp> getDimensionPage(PageDimensionReq pageDimensionCmd);
|
PageInfo<DimensionResp> getDimensionPage(PageDimensionReq pageDimensionCmd);
|
||||||
|
|
||||||
PageInfo<MetricResp> getMetricPage(PageMetricReq pageMetricCmd);
|
PageInfo<MetricResp> getMetricPage(PageMetricReq pageMetricCmd);
|
||||||
|
|
||||||
List<DomainResp> getDomainList(User user);
|
List<DomainResp> getDomainList(User user);
|
||||||
|
|
||||||
List<ModelResp> getModelList(AuthType authType, Long domainId, User user);
|
List<ModelResp> getModelList(AuthType authType, Long domainId, User user);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ import com.tencent.supersonic.chat.api.pojo.ChatContext;
|
|||||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines the contract for a semantic parser that can analyze natural language query
|
* A semantic parser understands user queries and extracts semantic information.
|
||||||
* and extract meaning from it.
|
* It could leverage either rule-based or LLM-based approach to identify query intent
|
||||||
*
|
* and extract related semantic items from the query.
|
||||||
* The semantic parser uses either rule-based or model-based algorithms to identify query intent
|
|
||||||
* and related semantic items described in the query.
|
|
||||||
*/
|
*/
|
||||||
public interface SemanticParser {
|
public interface SemanticParser {
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
|||||||
import org.apache.calcite.sql.parser.SqlParseException;
|
import org.apache.calcite.sql.parser.SqlParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class defines the contract for a semantic query that executes specific type of
|
* A semantic query executes specific type of query based on the results of semantic parsing.
|
||||||
* query based on the results of semantic parsing.
|
|
||||||
*/
|
*/
|
||||||
public interface SemanticQuery {
|
public interface SemanticQuery {
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import lombok.Data;
|
|||||||
public class ChatContext {
|
public class ChatContext {
|
||||||
|
|
||||||
private Integer chatId;
|
private Integer chatId;
|
||||||
|
private Integer agentId;
|
||||||
private String queryText;
|
private String queryText;
|
||||||
private SemanticParseInfo parseInfo = new SemanticParseInfo();
|
private SemanticParseInfo parseInfo = new SemanticParseInfo();
|
||||||
private String user;
|
private String user;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo;
|
package com.tencent.supersonic.chat.api.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ModelSchema {
|
public class ModelSchema {
|
||||||
@@ -32,6 +33,7 @@ public class ModelSchema {
|
|||||||
break;
|
break;
|
||||||
case VALUE:
|
case VALUE:
|
||||||
element = dimensionValues.stream().filter(e -> e.getId() == elementID).findFirst();
|
element = dimensionValues.stream().filter(e -> e.getId() == elementID).findFirst();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ package com.tencent.supersonic.chat.api.pojo;
|
|||||||
|
|
||||||
import com.tencent.supersonic.chat.api.component.SemanticQuery;
|
import com.tencent.supersonic.chat.api.component.SemanticQuery;
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class QueryContext {
|
public class QueryContext {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.tencent.supersonic.chat.api.pojo;
|
|||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -11,31 +12,19 @@ import lombok.NoArgsConstructor;
|
|||||||
@Data
|
@Data
|
||||||
@Getter
|
@Getter
|
||||||
@Builder
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
//@AllArgsConstructor
|
|
||||||
public class SchemaElement implements Serializable {
|
public class SchemaElement implements Serializable {
|
||||||
|
|
||||||
private Long model;
|
private Long model;
|
||||||
private Long id;
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
private String bizName;
|
private String bizName;
|
||||||
private Long useCnt;
|
private Long useCnt;
|
||||||
private SchemaElementType type;
|
private SchemaElementType type;
|
||||||
|
|
||||||
private List<String> alias;
|
private List<String> alias;
|
||||||
|
|
||||||
// public SchemaElement() {
|
private List<SchemaValueMap> schemaValueMaps;
|
||||||
// }
|
|
||||||
|
|
||||||
public SchemaElement(Long model, Long id, String name, String bizName,
|
|
||||||
Long useCnt, SchemaElementType type, List<String> alias) {
|
|
||||||
this.model = model;
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.bizName = bizName;
|
|
||||||
this.useCnt = useCnt;
|
|
||||||
this.type = type;
|
|
||||||
this.alias = alias;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
@@ -56,4 +45,5 @@ public class SchemaElement implements Serializable {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(model, id, name, bizName, useCnt, type);
|
return Objects.hashCode(model, id, name, bizName, useCnt, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ public class SchemaMapInfo {
|
|||||||
return modelElementMatches;
|
return modelElementMatches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setModelElementMatches(Map<Long, List<SchemaElementMatch>> modelElementMatches) {
|
||||||
|
this.modelElementMatches = modelElementMatches;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMatchedElements(Long model, List<SchemaElementMatch> elementMatches) {
|
public void setMatchedElements(Long model, List<SchemaElementMatch> elementMatches) {
|
||||||
modelElementMatches.put(model, elementMatches);
|
modelElementMatches.put(model, elementMatches);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<>();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -1,23 +1,26 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo;
|
package com.tencent.supersonic.chat.api.pojo;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||||
import com.tencent.supersonic.common.pojo.DateConf;
|
import com.tencent.supersonic.common.pojo.DateConf;
|
||||||
import com.tencent.supersonic.common.pojo.Order;
|
import com.tencent.supersonic.common.pojo.Order;
|
||||||
import com.tencent.supersonic.common.pojo.enums.AggregateTypeEnum;
|
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 lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class SemanticParseInfo {
|
public class SemanticParseInfo {
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
private String queryMode;
|
private String queryMode;
|
||||||
private SchemaElement model;
|
private SchemaElement model;
|
||||||
private Set<SchemaElement> metrics = new TreeSet<>(new SchemaNameLengthComparator());
|
private Set<SchemaElement> metrics = new TreeSet<>(new SchemaNameLengthComparator());
|
||||||
@@ -33,7 +36,7 @@ public class SemanticParseInfo {
|
|||||||
private double score;
|
private double score;
|
||||||
private List<SchemaElementMatch> elementMatches = new ArrayList<>();
|
private List<SchemaElementMatch> elementMatches = new ArrayList<>();
|
||||||
private Map<String, Object> properties = new HashMap<>();
|
private Map<String, Object> properties = new HashMap<>();
|
||||||
|
private EntityInfo entityInfo;
|
||||||
public Long getModelId() {
|
public Long getModelId() {
|
||||||
return model != null ? model.getId() : 0L;
|
return model != null ? model.getId() : 0L;
|
||||||
}
|
}
|
||||||
@@ -43,7 +46,6 @@ public class SemanticParseInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class SchemaNameLengthComparator implements Comparator<SchemaElement> {
|
private static class SchemaNameLengthComparator implements Comparator<SchemaElement> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(SchemaElement o1, SchemaElement o2) {
|
public int compare(SchemaElement o1, SchemaElement o2) {
|
||||||
int len1 = o1.getName().length();
|
int len1 = o1.getName().length();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import java.util.Map;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class SemanticSchema implements Serializable {
|
public class SemanticSchema implements Serializable {
|
||||||
|
|
||||||
private List<ModelSchema> modelSchemaList;
|
private List<ModelSchema> modelSchemaList;
|
||||||
|
|
||||||
public SemanticSchema(List<ModelSchema> modelSchemaList) {
|
public SemanticSchema(List<ModelSchema> modelSchemaList) {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.request;
|
package com.tencent.supersonic.chat.api.pojo.request;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ChatAggConfigReq {
|
public class ChatAggConfigReq {
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.request;
|
package com.tencent.supersonic.chat.api.pojo.request;
|
||||||
|
|
||||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* extended information command about model
|
* extended information command about model
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package com.tencent.supersonic.chat.api.pojo.request;
|
|||||||
|
|
||||||
|
|
||||||
import com.tencent.supersonic.common.pojo.Constants;
|
import com.tencent.supersonic.common.pojo.Constants;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ChatDefaultConfigReq {
|
public class ChatDefaultConfigReq {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.request;
|
package com.tencent.supersonic.chat.api.pojo.request;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ChatDetailConfigReq {
|
public class ChatDetailConfigReq {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.tencent.supersonic.chat.api.pojo.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DimensionValueReq {
|
||||||
|
private Long modelId;
|
||||||
|
|
||||||
|
private String bizName;
|
||||||
|
|
||||||
|
private Object value;
|
||||||
|
}
|
||||||
@@ -7,10 +7,12 @@ import lombok.Data;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ExecuteQueryReq {
|
public class ExecuteQueryReq {
|
||||||
|
|
||||||
private User user;
|
private User user;
|
||||||
|
private Integer agentId;
|
||||||
private Integer chatId;
|
private Integer chatId;
|
||||||
private String queryText;
|
private String queryText;
|
||||||
|
private Long queryId = 7L;
|
||||||
|
private Integer parseId = 2;
|
||||||
private SemanticParseInfo parseInfo;
|
private SemanticParseInfo parseInfo;
|
||||||
private boolean saveAnswer = true;
|
private boolean saveAnswer = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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<>();
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.request;
|
package com.tencent.supersonic.chat.api.pojo.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* advanced knowledge config
|
* advanced knowledge config
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.request;
|
package com.tencent.supersonic.chat.api.pojo.request;
|
||||||
|
|
||||||
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +32,4 @@ public class KnowledgeInfoReq {
|
|||||||
* advanced knowledge config for single item
|
* advanced knowledge config for single item
|
||||||
*/
|
*/
|
||||||
private KnowledgeAdvancedConfig knowledgeAdvancedConfig;
|
private KnowledgeAdvancedConfig knowledgeAdvancedConfig;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,20 @@ package com.tencent.supersonic.chat.api.pojo.request;
|
|||||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||||
import com.tencent.supersonic.common.pojo.DateConf;
|
import com.tencent.supersonic.common.pojo.DateConf;
|
||||||
import com.tencent.supersonic.common.pojo.Order;
|
import com.tencent.supersonic.common.pojo.Order;
|
||||||
|
import com.tencent.supersonic.common.pojo.enums.AggregateTypeEnum;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class QueryDataReq {
|
public class QueryDataReq {
|
||||||
|
|
||||||
String queryMode;
|
String queryMode;
|
||||||
SchemaElement model;
|
SchemaElement model;
|
||||||
Set<SchemaElement> metrics = new HashSet<>();
|
Set<SchemaElement> metrics = new HashSet<>();
|
||||||
Set<SchemaElement> dimensions = new HashSet<>();
|
Set<SchemaElement> dimensions = new HashSet<>();
|
||||||
Set<QueryFilter> dimensionFilters = new HashSet<>();
|
Set<QueryFilter> dimensionFilters = new HashSet<>();
|
||||||
Set<QueryFilter> metricFilters = new HashSet<>();
|
Set<QueryFilter> metricFilters = new HashSet<>();
|
||||||
|
private AggregateTypeEnum aggType = AggregateTypeEnum.NONE;
|
||||||
private Set<Order> orders = new HashSet<>();
|
private Set<Order> orders = new HashSet<>();
|
||||||
private DateConf dateInfo;
|
private DateConf dateInfo;
|
||||||
private Long limit;
|
private Long limit;
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.request;
|
package com.tencent.supersonic.chat.api.pojo.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class QueryFilters {
|
public class QueryFilters {
|
||||||
|
|
||||||
private List<QueryFilter> filters = new ArrayList<>();
|
private List<QueryFilter> filters = new ArrayList<>();
|
||||||
private Map<String, Object> params = new HashMap<>();
|
private Map<String, Object> params = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import lombok.Data;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class QueryReq {
|
public class QueryReq {
|
||||||
|
|
||||||
private String queryText;
|
private String queryText;
|
||||||
private Integer chatId;
|
private Integer chatId;
|
||||||
private Long modelId = 0L;
|
private Long modelId = 0L;
|
||||||
private User user;
|
private User user;
|
||||||
private QueryFilters queryFilters;
|
private QueryFilters queryFilters;
|
||||||
private boolean saveAnswer = true;
|
private boolean saveAnswer = true;
|
||||||
|
private Integer agentId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,5 @@ import lombok.Data;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class AggregateInfo {
|
public class AggregateInfo {
|
||||||
|
|
||||||
private List<MetricInfo> metricInfos = new ArrayList<>();
|
private List<MetricInfo> metricInfos = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ 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.KnowledgeAdvancedConfig;
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
|
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ChatAggRichConfigResp {
|
public class ChatAggRichConfigResp {
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ 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.ChatDetailConfigReq;
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
||||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
|||||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ package com.tencent.supersonic.chat.api.pojo.response;
|
|||||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.ChatDefaultConfigReq;
|
import com.tencent.supersonic.chat.api.pojo.request.ChatDefaultConfigReq;
|
||||||
import com.tencent.supersonic.common.pojo.Constants;
|
import com.tencent.supersonic.common.pojo.Constants;
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ChatDefaultRichConfigResp {
|
public class ChatDefaultRichConfigResp {
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ 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.KnowledgeAdvancedConfig;
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
|
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ChatDetailRichConfigResp {
|
public class ChatDetailRichConfigResp {
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.response;
|
package com.tencent.supersonic.chat.api.pojo.response;
|
||||||
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class EntityRichInfoResp {
|
public class EntityRichInfoResp {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* entity alias
|
* entity alias
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.response;
|
package com.tencent.supersonic.chat.api.pojo.response;
|
||||||
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||||
import java.util.List;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Getter
|
@Getter
|
||||||
@@ -14,9 +15,9 @@ import lombok.NoArgsConstructor;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class ParseResp {
|
public class ParseResp {
|
||||||
|
|
||||||
private Integer chatId;
|
private Integer chatId;
|
||||||
private String queryText;
|
private String queryText;
|
||||||
|
private Long queryId;
|
||||||
private ParseState state;
|
private ParseState state;
|
||||||
private List<SemanticParseInfo> selectedParses;
|
private List<SemanticParseInfo> selectedParses;
|
||||||
private List<SemanticParseInfo> candidateParses;
|
private List<SemanticParseInfo> candidateParses;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.response;
|
package com.tencent.supersonic.chat.api.pojo.response;
|
||||||
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
||||||
import java.util.List;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class RecommendQuestionResp {
|
public class RecommendQuestionResp {
|
||||||
|
|
||||||
private Long modelId;
|
private Long modelId;
|
||||||
private List<RecommendedQuestionReq> recommendedQuestions;
|
private List<RecommendedQuestionReq> recommendedQuestions;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.tencent.supersonic.chat.api.pojo.response;
|
package com.tencent.supersonic.chat.api.pojo.response;
|
||||||
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||||
import java.util.List;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class RecommendResp {
|
public class RecommendResp {
|
||||||
|
|
||||||
private List<SchemaElement> dimensions;
|
private List<SchemaElement> dimensions;
|
||||||
private List<SchemaElement> metrics;
|
private List<SchemaElement> metrics;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.tencent.supersonic.chat.api.pojo.response;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class SearchResp {
|
public class SearchResp {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.tencent.supersonic.chat.api.pojo.response;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ShowCaseResp {
|
||||||
|
|
||||||
|
private Map<Long, List<QueryResp>> showCaseMap;
|
||||||
|
|
||||||
|
private int pageSize;
|
||||||
|
|
||||||
|
private int current;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -40,12 +40,6 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.plexpt</groupId>
|
|
||||||
<artifactId>chatgpt</artifactId>
|
|
||||||
<version>4.1.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
@@ -142,6 +136,14 @@
|
|||||||
<artifactId>xk-time</artifactId>
|
<artifactId>xk-time</artifactId>
|
||||||
<version>${xk.time.version}</version>
|
<version>${xk.time.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-inline</artifactId>
|
||||||
|
<version>${mockito-inline.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.tencent.supersonic.chat.agent;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.tencent.supersonic.chat.agent.tool.AgentToolType;
|
||||||
|
import com.tencent.supersonic.common.pojo.RecordInfo;
|
||||||
|
import java.util.Objects;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Agent extends RecordInfo {
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
private Integer enableSearch;
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
//0 offline, 1 online
|
||||||
|
private Integer status;
|
||||||
|
private List<String> examples;
|
||||||
|
private String agentConfig;
|
||||||
|
public List<String> getTools(AgentToolType type) {
|
||||||
|
Map map = JSONObject.parseObject(agentConfig, Map.class);
|
||||||
|
if (CollectionUtils.isEmpty(map) || map.get("tools") == null) {
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
List<Map> toolList = (List) map.get("tools");
|
||||||
|
return toolList.stream()
|
||||||
|
.filter(tool -> {
|
||||||
|
if (Objects.isNull(type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return type.name().equals(tool.get("type"));
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.map(JSONObject::toJSONString)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean enableSearch() {
|
||||||
|
return enableSearch != null && enableSearch == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.tencent.supersonic.chat.agent;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.tencent.supersonic.chat.agent.tool.AgentTool;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AgentConfig {
|
||||||
|
|
||||||
|
List<AgentTool> tools = Lists.newArrayList();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.tencent.supersonic.chat.agent.tool;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AgentTool {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private AgentToolType type;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.tencent.supersonic.chat.agent.tool;
|
||||||
|
|
||||||
|
public enum AgentToolType {
|
||||||
|
RULE,
|
||||||
|
DSL,
|
||||||
|
PLUGIN,
|
||||||
|
INTERPRET
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.tencent.supersonic.chat.agent.tool;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DslTool extends AgentTool {
|
||||||
|
|
||||||
|
private List<Long> modelIds;
|
||||||
|
|
||||||
|
private List<String> exampleQuestions;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.tencent.supersonic.chat.agent.tool;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.parser.llm.interpret.MetricOption;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MetricInterpretTool extends AgentTool {
|
||||||
|
|
||||||
|
private Long modelId;
|
||||||
|
|
||||||
|
private List<MetricOption> metricOptions;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.tencent.supersonic.chat.agent.tool;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PluginTool extends AgentTool {
|
||||||
|
|
||||||
|
private List<Long> plugins;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.tencent.supersonic.chat.agent.tool;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class RuleQueryTool extends AgentTool {
|
||||||
|
|
||||||
|
private List<Long> modelIds;
|
||||||
|
|
||||||
|
private List<String> queryModes;
|
||||||
|
|
||||||
|
public boolean isContainsAllModel() {
|
||||||
|
return CollectionUtils.isNotEmpty(modelIds) && modelIds.contains(-1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,11 +3,9 @@ package com.tencent.supersonic.chat.config;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Data
|
@Data
|
||||||
|
@Configuration
|
||||||
public class AggregatorConfig {
|
public class AggregatorConfig {
|
||||||
|
|
||||||
@Value("${metric.aggregator.ratio.enable:true}")
|
@Value("${metric.aggregator.ratio.enable:true}")
|
||||||
private Boolean enableRatio;
|
private Boolean enableRatio;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ package com.tencent.supersonic.chat.config;
|
|||||||
import com.tencent.supersonic.chat.api.pojo.request.ChatAggConfigReq;
|
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.ChatDetailConfigReq;
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
||||||
import com.tencent.supersonic.common.pojo.RecordInfo;
|
|
||||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||||
import java.util.List;
|
import com.tencent.supersonic.common.pojo.RecordInfo;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ToString
|
@ToString
|
||||||
public class ChatConfig {
|
public class ChatConfig {
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@Data
|
@Data
|
||||||
public class FunctionCallInfoConfig {
|
public class FunctionCallInfoConfig {
|
||||||
|
|
||||||
@Value("${functionCall.url:}")
|
@Value("${functionCall.url:}")
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
@Value("${funtionCall.plugin.select.path:/plugin_selection}")
|
||||||
|
private String pluginSelectPath;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class LLMConfig {
|
|||||||
@Value("${llm.url:}")
|
@Value("${llm.url:}")
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
@Value("${query2sql.path:query2sql}")
|
@Value("${query2sql.path:/query2sql}")
|
||||||
private String queryToSqlPath;
|
private String queryToSqlPath;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.tencent.supersonic.chat.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Data
|
||||||
|
@PropertySource("classpath:optimization.properties")
|
||||||
|
//@ComponentScan(basePackages = "com.tencent.supersonic.chat")
|
||||||
|
public class OptimizationConfig {
|
||||||
|
|
||||||
|
@Value("${one.detection.size}")
|
||||||
|
private Integer oneDetectionSize;
|
||||||
|
@Value("${one.detection.max.size}")
|
||||||
|
private Integer oneDetectionMaxSize;
|
||||||
|
|
||||||
|
@Value("${metric.dimension.min.threshold}")
|
||||||
|
private Double metricDimensionMinThresholdConfig;
|
||||||
|
|
||||||
|
@Value("${metric.dimension.threshold}")
|
||||||
|
private Double metricDimensionThresholdConfig;
|
||||||
|
|
||||||
|
@Value("${dimension.value.threshold}")
|
||||||
|
private Double dimensionValueThresholdConfig;
|
||||||
|
|
||||||
|
@Value("${function.bonus.threshold}")
|
||||||
|
private Double functionBonusThreshold;
|
||||||
|
|
||||||
|
@Value("${long.text.threshold}")
|
||||||
|
private Double longTextThreshold;
|
||||||
|
|
||||||
|
@Value("${short.text.threshold}")
|
||||||
|
private Double shortTextThreshold;
|
||||||
|
|
||||||
|
@Value("${query.text.length.threshold}")
|
||||||
|
private Integer queryTextLengthThreshold;
|
||||||
|
|
||||||
|
@Value("${candidate.threshold}")
|
||||||
|
private Double candidateThreshold;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.component.SemanticCorrector;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||||
|
import com.tencent.supersonic.common.util.ContextUtils;
|
||||||
|
import com.tencent.supersonic.knowledge.service.SchemaService;
|
||||||
|
import com.tencent.supersonic.semantic.api.model.enums.TimeDimensionEnum;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public abstract class BaseSemanticCorrector implements SemanticCorrector {
|
||||||
|
public static final String DATE_FIELD = "数据日期";
|
||||||
|
protected Map<String, String> getFieldToBizName(Long modelId) {
|
||||||
|
|
||||||
|
SemanticSchema semanticSchema = ContextUtils.getBean(SchemaService.class).getSemanticSchema();
|
||||||
|
|
||||||
|
List<SchemaElement> dbAllFields = new ArrayList<>();
|
||||||
|
dbAllFields.addAll(semanticSchema.getMetrics());
|
||||||
|
dbAllFields.addAll(semanticSchema.getDimensions());
|
||||||
|
|
||||||
|
Map<String, String> result = dbAllFields.stream()
|
||||||
|
.filter(entry -> entry.getModel().equals(modelId))
|
||||||
|
.collect(Collectors.toMap(SchemaElement::getName, a -> a.getBizName(), (k1, k2) -> k1));
|
||||||
|
result.put(DATE_FIELD, TimeDimensionEnum.DAY.getName());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.chat.parser.llm.dsl.DSLDateHelper;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class DateFieldCorrector extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
|
|
||||||
|
String sql = semanticCorrectInfo.getSql();
|
||||||
|
List<String> whereFields = SqlParserSelectHelper.getWhereFields(sql);
|
||||||
|
if (CollectionUtils.isEmpty(whereFields) || !whereFields.contains(DATE_FIELD)) {
|
||||||
|
String currentDate = DSLDateHelper.getReferenceDate(semanticCorrectInfo.getParseInfo().getModelId());
|
||||||
|
sql = SqlParserUpdateHelper.addWhere(sql, DATE_FIELD, currentDate);
|
||||||
|
}
|
||||||
|
semanticCorrectInfo.setPreSql(semanticCorrectInfo.getSql());
|
||||||
|
semanticCorrectInfo.setSql(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class FieldCorrector extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
|
String preSql = semanticCorrectInfo.getSql();
|
||||||
|
semanticCorrectInfo.setPreSql(preSql);
|
||||||
|
String sql = SqlParserUpdateHelper.replaceFields(preSql,
|
||||||
|
getFieldToBizName(semanticCorrectInfo.getParseInfo().getModelId()));
|
||||||
|
semanticCorrectInfo.setSql(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.chat.parser.llm.dsl.DSLParseResult;
|
||||||
|
import com.tencent.supersonic.chat.query.llm.dsl.LLMReq;
|
||||||
|
import com.tencent.supersonic.chat.query.llm.dsl.LLMReq.ElementValue;
|
||||||
|
import com.tencent.supersonic.common.pojo.Constants;
|
||||||
|
import com.tencent.supersonic.common.util.JsonUtil;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class FieldNameCorrector extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
|
|
||||||
|
Object context = semanticCorrectInfo.getParseInfo().getProperties().get(Constants.CONTEXT);
|
||||||
|
if (Objects.isNull(context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DSLParseResult dslParseResult = JsonUtil.toObject(JsonUtil.toString(context), DSLParseResult.class);
|
||||||
|
if (Objects.isNull(dslParseResult) || Objects.isNull(dslParseResult.getLlmReq())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LLMReq llmReq = dslParseResult.getLlmReq();
|
||||||
|
List<ElementValue> linking = llmReq.getLinking();
|
||||||
|
if (CollectionUtils.isEmpty(linking)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Set<String>> fieldValueToFieldNames = linking.stream().collect(
|
||||||
|
Collectors.groupingBy(ElementValue::getFieldValue,
|
||||||
|
Collectors.mapping(ElementValue::getFieldName, Collectors.toSet())));
|
||||||
|
|
||||||
|
String preSql = semanticCorrectInfo.getSql();
|
||||||
|
semanticCorrectInfo.setPreSql(preSql);
|
||||||
|
String sql = SqlParserUpdateHelper.replaceFieldNameByValue(preSql, fieldValueToFieldNames);
|
||||||
|
semanticCorrectInfo.setSql(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SchemaValueMap;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||||
|
import com.tencent.supersonic.common.util.ContextUtils;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import com.tencent.supersonic.knowledge.service.SchemaService;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.logging.log4j.util.Strings;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class FieldValueCorrector extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
|
SemanticSchema semanticSchema = ContextUtils.getBean(SchemaService.class).getSemanticSchema();
|
||||||
|
Long modelId = semanticCorrectInfo.getParseInfo().getModel().getId();
|
||||||
|
List<SchemaElement> dimensions = semanticSchema.getDimensions().stream()
|
||||||
|
.filter(schemaElement -> modelId.equals(schemaElement.getModel()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(dimensions)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Map<String, String>> aliasAndBizNameToTechName = getAliasAndBizNameToTechName(dimensions);
|
||||||
|
String preSql = semanticCorrectInfo.getSql();
|
||||||
|
semanticCorrectInfo.setPreSql(preSql);
|
||||||
|
String sql = SqlParserUpdateHelper.replaceValue(preSql, aliasAndBizNameToTechName);
|
||||||
|
semanticCorrectInfo.setSql(sql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Map<String, Map<String, String>> getAliasAndBizNameToTechName(List<SchemaElement> dimensions) {
|
||||||
|
if (CollectionUtils.isEmpty(dimensions)) {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Map<String, String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
for (SchemaElement dimension : dimensions) {
|
||||||
|
if (Objects.isNull(dimension)
|
||||||
|
|| Strings.isEmpty(dimension.getBizName())
|
||||||
|
|| CollectionUtils.isEmpty(dimension.getSchemaValueMaps())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String bizName = dimension.getBizName();
|
||||||
|
|
||||||
|
Map<String, String> aliasAndBizNameToTechName = new HashMap<>();
|
||||||
|
|
||||||
|
for (SchemaValueMap valueMap : dimension.getSchemaValueMaps()) {
|
||||||
|
if (Objects.isNull(valueMap) || Strings.isEmpty(valueMap.getTechName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Strings.isNotEmpty(valueMap.getBizName())) {
|
||||||
|
aliasAndBizNameToTechName.put(valueMap.getBizName(), valueMap.getTechName());
|
||||||
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(valueMap.getAlias())) {
|
||||||
|
valueMap.getAlias().stream().forEach(alias -> {
|
||||||
|
if (Strings.isNotEmpty(alias)) {
|
||||||
|
aliasAndBizNameToTechName.put(alias, valueMap.getTechName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(aliasAndBizNameToTechName)) {
|
||||||
|
result.put(bizName, aliasAndBizNameToTechName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class FunctionAliasCorrector extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
|
String replaceAlias = SqlParserUpdateHelper.replaceAlias(semanticCorrectInfo.getSql());
|
||||||
|
semanticCorrectInfo.setSql(replaceAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class FunctionCorrector extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
|
String preSql = semanticCorrectInfo.getSql();
|
||||||
|
semanticCorrectInfo.setPreSql(preSql);
|
||||||
|
String sql = SqlParserUpdateHelper.replaceFunction(preSql);
|
||||||
|
semanticCorrectInfo.setSql(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.request.QueryFilters;
|
||||||
|
import com.tencent.supersonic.common.pojo.Constants;
|
||||||
|
import com.tencent.supersonic.common.util.StringUtil;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.sf.jsqlparser.JSQLParserException;
|
||||||
|
import net.sf.jsqlparser.expression.Expression;
|
||||||
|
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class QueryFilterAppend extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) throws JSQLParserException {
|
||||||
|
String queryFilter = getQueryFilter(semanticCorrectInfo.getQueryFilters());
|
||||||
|
String preSql = semanticCorrectInfo.getSql();
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(queryFilter)) {
|
||||||
|
log.info("add queryFilter to preSql :{}", queryFilter);
|
||||||
|
Expression expression = CCJSqlParserUtil.parseCondExpression(queryFilter);
|
||||||
|
String sql = SqlParserUpdateHelper.addWhere(preSql, expression);
|
||||||
|
semanticCorrectInfo.setPreSql(preSql);
|
||||||
|
semanticCorrectInfo.setSql(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getQueryFilter(QueryFilters queryFilters) {
|
||||||
|
if (Objects.isNull(queryFilters) || CollectionUtils.isEmpty(queryFilters.getFilters())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return queryFilters.getFilters().stream()
|
||||||
|
.map(filter -> {
|
||||||
|
String bizNameWrap = StringUtil.getSpaceWrap(filter.getBizName());
|
||||||
|
String operatorWrap = StringUtil.getSpaceWrap(filter.getOperator().getValue());
|
||||||
|
String valueWrap = StringUtil.getCommaWrap(filter.getValue().toString());
|
||||||
|
return bizNameWrap + operatorWrap + valueWrap;
|
||||||
|
})
|
||||||
|
.collect(Collectors.joining(Constants.AND_UPPER));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import com.tencent.supersonic.semantic.api.model.enums.TimeDimensionEnum;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class SelectFieldAppendCorrector extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
|
String preSql = semanticCorrectInfo.getSql();
|
||||||
|
if (SqlParserSelectHelper.hasAggregateFunction(preSql)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<String> selectFields = new HashSet<>(SqlParserSelectHelper.getSelectFields(preSql));
|
||||||
|
Set<String> whereFields = new HashSet<>(SqlParserSelectHelper.getWhereFields(preSql));
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(selectFields) || CollectionUtils.isEmpty(whereFields)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
whereFields.addAll(SqlParserSelectHelper.getOrderByFields(preSql));
|
||||||
|
whereFields.removeAll(selectFields);
|
||||||
|
whereFields.remove(TimeDimensionEnum.DAY.getName());
|
||||||
|
whereFields.remove(TimeDimensionEnum.WEEK.getName());
|
||||||
|
whereFields.remove(TimeDimensionEnum.MONTH.getName());
|
||||||
|
String replaceFields = SqlParserUpdateHelper.addFieldsToSelect(preSql, new ArrayList<>(whereFields));
|
||||||
|
semanticCorrectInfo.setPreSql(preSql);
|
||||||
|
semanticCorrectInfo.setSql(replaceFields);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.tencent.supersonic.chat.corrector;
|
||||||
|
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SemanticCorrectInfo;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlParserUpdateHelper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class TableNameCorrector extends BaseSemanticCorrector {
|
||||||
|
|
||||||
|
public static final String TABLE_PREFIX = "t_";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void correct(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
|
Long modelId = semanticCorrectInfo.getParseInfo().getModelId();
|
||||||
|
String preSql = semanticCorrectInfo.getSql();
|
||||||
|
semanticCorrectInfo.setPreSql(preSql);
|
||||||
|
String sql = SqlParserUpdateHelper.replaceTable(preSql, TABLE_PREFIX + modelId);
|
||||||
|
semanticCorrectInfo.setSql(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,19 +2,19 @@ package com.tencent.supersonic.chat.mapper;
|
|||||||
|
|
||||||
|
|
||||||
import com.tencent.supersonic.chat.api.component.SchemaMapper;
|
import com.tencent.supersonic.chat.api.component.SchemaMapper;
|
||||||
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
import com.tencent.supersonic.chat.api.pojo.QueryContext;
|
||||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.SchemaMapInfo;
|
import com.tencent.supersonic.chat.api.pojo.SchemaMapInfo;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
|
||||||
|
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
||||||
import com.tencent.supersonic.chat.service.SemanticService;
|
import com.tencent.supersonic.chat.service.SemanticService;
|
||||||
import com.tencent.supersonic.common.util.ContextUtils;
|
import com.tencent.supersonic.common.util.ContextUtils;
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user