diff --git a/docs/en_US/EasyScheduler-FAQ.md b/docs/en_US/EasyScheduler-FAQ.md
index b55b0e2413..65b3add815 100644
--- a/docs/en_US/EasyScheduler-FAQ.md
+++ b/docs/en_US/EasyScheduler-FAQ.md
@@ -50,7 +50,7 @@ A: We also support **the priority of processes and tasks**. Priority We have fiv
----
-## Q: Escheduler-grpc gives an error
+## Q: dolphinscheduler-grpc gives an error
A: Execute in the root directory: mvn -U clean package assembly:assembly -Dmaven.test.skip=true , then refresh the entire project
@@ -70,11 +70,11 @@ A: Install **npm install node-sass --unsafe-perm** separately, then **npm instal
## Q: UI cannot log in normally.
-A: 1, if it is node startup, check whether the .env API_BASE configuration under escheduler-ui is the Api Server service address.
+A: 1, if it is node startup, check whether the .env API_BASE configuration under dolphinscheduler-ui is the Api Server service address.
- 2, If it is nginx booted and installed via **install-escheduler-ui.sh**, check if the proxy_pass configuration in **/etc/nginx/conf.d/escheduler.conf** is the Api Server service. address
+ 2, If it is nginx booted and installed via **install-dolphinscheduler-ui.sh**, check if the proxy_pass configuration in **/etc/nginx/conf.d/dolphinscheduler.conf** is the Api Server service. address
- 3, if the above configuration is correct, then please check if the Api Server service is normal, curl http://192.168.xx.xx:12345/escheduler/users/get-user-info, check the Api Server log, if Prompt cn.escheduler.api.interceptor.LoginHandlerInterceptor:[76] - session info is null, which proves that the Api Server service is normal.
+ 3, if the above configuration is correct, then please check if the Api Server service is normal, curl http://192.168.xx.xx:12345/dolphinscheduler/users/get-user-info, check the Api Server log, if Prompt cn.dolphinscheduler.api.interceptor.LoginHandlerInterceptor:[76] - session info is null, which proves that the Api Server service is normal.
4, if there is no problem above, you need to check if **server.context-path and server.port configuration** in **application.properties** is correct
@@ -84,7 +84,7 @@ A: 1, if it is node startup, check whether the .env API_BASE configuration under
A: 1, first **check whether the MasterServer service exists through jps**, or directly check whether there is a master service in zk from the service monitoring.
- 2,If there is a master service, check **the command status statistics** or whether new records are added in **t_escheduler_error_command**. If it is added, **please check the message field.**
+ 2,If there is a master service, check **the command status statistics** or whether new records are added in **t_dolphinscheduler_error_command**. If it is added, **please check the message field.**
---
@@ -102,9 +102,9 @@ A: 1, **first check whether the WorkerServer service exists through jps**, or
A: Provide Docker image and Dockerfile.
-Docker image address: https://hub.docker.com/r/escheduler/escheduler_images
+Docker image address: https://hub.docker.com/r/dolphinscheduler/dolphinscheduler_images
-Dockerfile address: https://github.com/qiaozhanwei/escheduler_dockerfile/tree/master/docker_escheduler
+Dockerfile address: https://github.com/qiaozhanwei/dolphinscheduler_dockerfile/tree/master/docker_dolphinscheduler
------
@@ -112,9 +112,9 @@ Dockerfile address: https://github.com/qiaozhanwei/escheduler_dockerfile/tree/ma
A: 1, if the replacement variable contains special characters, **use the \ transfer character to transfer**
- 2, installPath="/data1_1T/escheduler", **this directory can not be the same as the install.sh directory currently installed with one click.**
+ 2, installPath="/data1_1T/dolphinscheduler", **this directory can not be the same as the install.sh directory currently installed with one click.**
- 3, deployUser = "escheduler", **the deployment user must have sudo privileges**, because the worker is executed by sudo -u tenant sh xxx.command
+ 3, deployUser = "dolphinscheduler", **the deployment user must have sudo privileges**, because the worker is executed by sudo -u tenant sh xxx.command
4, monitorServerState = "false", whether the service monitoring script is started, the default is not to start the service monitoring script. **If the service monitoring script is started, the master and worker services are monitored every 5 minutes, and if the machine is down, it will automatically restart.**
@@ -126,7 +126,7 @@ A: 1, if the replacement variable contains special characters, **use the \ tra
## Q : Process definition and process instance offline exception
-A : For **versions prior to 1.0.4**, modify the code under the escheduler-api cn.escheduler.api.quartz package.
+A : For **versions prior to 1.0.4**, modify the code under the dolphinscheduler-api cn.dolphinscheduler.api.quartz package.
```
public boolean deleteJob(String jobName, String jobGroupName) {
@@ -207,7 +207,7 @@ A: 1, in **the process definition list**, click the **Start** button.
## Q : Python task setting Python version
-A: 1,**for the version after 1.0.3** only need to modify PYTHON_HOME in conf/env/.escheduler_env.sh
+A: 1,**for the version after 1.0.3** only need to modify PYTHON_HOME in conf/env/.dolphinscheduler_env.sh
```
export PYTHON_HOME=/bin/python
diff --git a/docs/en_US/SUMMARY.md b/docs/en_US/SUMMARY.md
index 397a4a110c..63be19a451 100644
--- a/docs/en_US/SUMMARY.md
+++ b/docs/en_US/SUMMARY.md
@@ -34,7 +34,7 @@
* Backend development documentation
* [Environmental requirements](backend-development.md#Environmental requirements)
* [Project compilation](backend-development.md#Project compilation)
-* [Interface documentation](http://52.82.13.76:8888/escheduler/doc.html?language=en_US&lang=en)
+* [Interface documentation](http://52.82.13.76:8888/dolphinscheduler/doc.html?language=en_US&lang=en)
* FAQ
* [FAQ](EasyScheduler-FAQ.md)
* EasyScheduler upgrade documentation
diff --git a/docs/en_US/backend-deployment.md b/docs/en_US/backend-deployment.md
index 934a005f6b..68c8b4bd9a 100644
--- a/docs/en_US/backend-deployment.md
+++ b/docs/en_US/backend-deployment.md
@@ -7,7 +7,7 @@ There are two deployment modes for the backend:
## Preparations
-Download the latest version of the installation package, download address: [gitee download](https://gitee.com/easyscheduler/EasyScheduler/attach_files/) or [github download](https://github.com/analysys/EasyScheduler/releases), download escheduler-backend-x.x.x.tar.gz(back-end referred to as escheduler-backend),escheduler-ui-x.x.x.tar.gz(front-end referred to as escheduler-ui)
+Download the latest version of the installation package, download address: [gitee download](https://gitee.com/easyscheduler/EasyScheduler/attach_files/) or [github download](https://github.com/apache/incubator-dolphinscheduler/releases), download dolphinscheduler-backend-x.x.x.tar.gz(back-end referred to as dolphinscheduler-backend),dolphinscheduler-ui-x.x.x.tar.gz(front-end referred to as dolphinscheduler-ui)
@@ -32,8 +32,8 @@ Download the latest version of the installation package, download address: [gi
```
vi /etc/sudoers
-# For example, the deployment user is an escheduler account
-escheduler ALL=(ALL) NOPASSWD: NOPASSWD: ALL
+# For example, the deployment user is an dolphinscheduler account
+dolphinscheduler ALL=(ALL) NOPASSWD: NOPASSWD: ALL
# And you need to comment out the Default requiretty line
#Default requiretty
@@ -51,9 +51,9 @@ Configure SSH secret-free login on deployment machines and other installation ma
Execute the following command to create database and account
```
- CREATE DATABASE escheduler DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
- GRANT ALL PRIVILEGES ON escheduler.* TO '{user}'@'%' IDENTIFIED BY '{password}';
- GRANT ALL PRIVILEGES ON escheduler.* TO '{user}'@'localhost' IDENTIFIED BY '{password}';
+ CREATE DATABASE dolphinscheduler DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
+ GRANT ALL PRIVILEGES ON dolphinscheduler.* TO '{user}'@'%' IDENTIFIED BY '{password}';
+ GRANT ALL PRIVILEGES ON dolphinscheduler.* TO '{user}'@'localhost' IDENTIFIED BY '{password}';
flush privileges;
```
@@ -69,12 +69,12 @@ Configure SSH secret-free login on deployment machines and other installation ma
Execute scripts for creating tables and importing basic data
```
- sh ./script/create-escheduler.sh
+ sh ./script/create-dolphinscheduler.sh
```
#### Preparations 5: Modify the deployment directory permissions and operation parameters
- instruction of escheduler-backend directory
+ instruction of dolphinscheduler-backend directory
```directory
bin : Basic service startup script
@@ -85,11 +85,11 @@ sql : The project relies on SQL files
install.sh : One-click deployment script
```
-- Modify permissions (please modify the 'deployUser' to the corresponding deployment user) so that the deployment user has operational privileges on the escheduler-backend directory
+- Modify permissions (please modify the 'deployUser' to the corresponding deployment user) so that the deployment user has operational privileges on the dolphinscheduler-backend directory
- `sudo chown -R deployUser:deployUser escheduler-backend`
+ `sudo chown -R deployUser:deployUser dolphinscheduler-backend`
-- Modify the `.escheduler_env.sh` environment variable in the conf/env/directory
+- Modify the `.dolphinscheduler_env.sh` environment variable in the conf/env/directory
- Modify deployment parameters (depending on your server and business situation):
@@ -132,11 +132,11 @@ After successful deployment, the log can be viewed and stored in a specified fol
```logPath
logs/
- ├── escheduler-alert-server.log
- ├── escheduler-master-server.log
- |—— escheduler-worker-server.log
- |—— escheduler-api-server.log
- |—— escheduler-logger-server.log
+ ├── dolphinscheduler-alert-server.log
+ ├── dolphinscheduler-master-server.log
+ |—— dolphinscheduler-worker-server.log
+ |—— dolphinscheduler-api-server.log
+ |—— dolphinscheduler-logger-server.log
```
### Compile source code to deploy
@@ -151,7 +151,7 @@ After downloading the release version of the source package, unzip it into the r
* View directory
-After normal compilation, ./target/escheduler-{version}/ is generated in the current directory
+After normal compilation, ./target/dolphinscheduler-{version}/ is generated in the current directory
### Start-and-stop services commonly used in systems (for service purposes, please refer to System Architecture Design for details)
@@ -167,41 +167,41 @@ After normal compilation, ./target/escheduler-{version}/ is generated in the cur
* start and stop one master server
```master
-sh ./bin/escheduler-daemon.sh start master-server
-sh ./bin/escheduler-daemon.sh stop master-server
+sh ./bin/dolphinscheduler-daemon.sh start master-server
+sh ./bin/dolphinscheduler-daemon.sh stop master-server
```
* start and stop one worker server
```worker
-sh ./bin/escheduler-daemon.sh start worker-server
-sh ./bin/escheduler-daemon.sh stop worker-server
+sh ./bin/dolphinscheduler-daemon.sh start worker-server
+sh ./bin/dolphinscheduler-daemon.sh stop worker-server
```
* start and stop api server
```Api
-sh ./bin/escheduler-daemon.sh start api-server
-sh ./bin/escheduler-daemon.sh stop api-server
+sh ./bin/dolphinscheduler-daemon.sh start api-server
+sh ./bin/dolphinscheduler-daemon.sh stop api-server
```
* start and stop logger server
```Logger
-sh ./bin/escheduler-daemon.sh start logger-server
-sh ./bin/escheduler-daemon.sh stop logger-server
+sh ./bin/dolphinscheduler-daemon.sh start logger-server
+sh ./bin/dolphinscheduler-daemon.sh stop logger-server
```
* start and stop alert server
```Alert
-sh ./bin/escheduler-daemon.sh start alert-server
-sh ./bin/escheduler-daemon.sh stop alert-server
+sh ./bin/dolphinscheduler-daemon.sh start alert-server
+sh ./bin/dolphinscheduler-daemon.sh stop alert-server
```
## Database Upgrade
Database upgrade is a function added in version 1.0.2. The database can be upgraded automatically by executing the following command:
```upgrade
-sh ./script/upgrade-escheduler.sh
+sh ./script/upgrade-dolphinscheduler.sh
```
diff --git a/docs/en_US/backend-development.md b/docs/en_US/backend-development.md
index 10f7ba47f6..b287fad7bc 100644
--- a/docs/en_US/backend-development.md
+++ b/docs/en_US/backend-development.md
@@ -7,7 +7,7 @@
* [ZooKeeper](https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper)(3.4.6+) :Must be installed
* [Maven](http://maven.apache.org/download.cgi)(3.3+) :Must be installed
-Because the escheduler-rpc module in EasyScheduler uses Grpc, you need to use Maven to compile the generated classes.
+Because the dolphinscheduler-rpc module in EasyScheduler uses Grpc, you need to use Maven to compile the generated classes.
For those who are not familiar with maven, please refer to: [maven in five minutes](http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html)(3.3+)
http://maven.apache.org/install.html
@@ -23,7 +23,7 @@ After importing the EasyScheduler source code into the development tools such as
* View directory
-After normal compilation, it will generate ./target/escheduler-{version}/ in the current directory.
+After normal compilation, it will generate ./target/dolphinscheduler-{version}/ in the current directory.
```
bin
diff --git a/docs/en_US/frontend-deployment.md b/docs/en_US/frontend-deployment.md
index 919caf1485..d2a3cda0bb 100644
--- a/docs/en_US/frontend-deployment.md
+++ b/docs/en_US/frontend-deployment.md
@@ -10,7 +10,7 @@ The front-end has three deployment modes: automated deployment, manual deploymen
Please download the latest version of the installation package, download address: [gitee](https://gitee.com/easyscheduler/EasyScheduler/attach_files/)
-After downloading escheduler-ui-x.x.x.tar.gz,decompress`tar -zxvf escheduler-ui-x.x.x.tar.gz ./`and enter the`escheduler-ui`directory
+After downloading dolphinscheduler-ui-x.x.x.tar.gz,decompress`tar -zxvf dolphinscheduler-ui-x.x.x.tar.gz ./`and enter the`dolphinscheduler-ui`directory
@@ -21,7 +21,7 @@ Automated deployment is recommended for either of the following two ways
### Automated Deployment
-Edit the installation file`vi install-escheduler-ui.sh` in the` escheduler-ui` directory
+Edit the installation file`vi install-dolphinscheduler-ui.sh` in the` dolphinscheduler-ui` directory
Change the front-end access port and the back-end proxy interface address
@@ -35,7 +35,7 @@ esc_proxy_port="http://192.168.xx.xx:12345"
>Front-end automatic deployment based on Linux system `yum` operation, before deployment, please install and update`yum`
-under this directory, execute`./install-escheduler-ui.sh`
+under this directory, execute`./install-dolphinscheduler-ui.sh`
### Manual Deployment
@@ -63,7 +63,7 @@ server {
root /xx/dist; # the dist directory address decompressed by the front end above (self-modifying)
index index.html index.html;
}
- location /escheduler {
+ location /dolphinscheduler {
proxy_pass http://192.168.xx.xx:12345; # interface address (self-modifying)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
diff --git a/docs/en_US/frontend-development.md b/docs/en_US/frontend-development.md
index 286c598dbc..bb3e464fb7 100644
--- a/docs/en_US/frontend-development.md
+++ b/docs/en_US/frontend-development.md
@@ -23,7 +23,7 @@ Node package download (note version 8.9.4) `https://nodejs.org/download/release/
- #### Front-end project construction
-Use the command line mode `cd` enter the `escheduler-ui` project directory and execute `npm install` to pull the project dependency package.
+Use the command line mode `cd` enter the `dolphinscheduler-ui` project directory and execute `npm install` to pull the project dependency package.
> If `npm install` is very slow
@@ -34,7 +34,7 @@ Use the command line mode `cd` enter the `escheduler-ui` project directory and
- Create a new `.env` file or the interface that interacts with the backend
-Create a new` .env` file in the `escheduler-ui `directory, add the ip address and port of the backend service to the file, and use it to interact with the backend. The contents of the` .env` file are as follows:
+Create a new` .env` file in the `dolphinscheduler-ui `directory, add the ip address and port of the backend service to the file, and use it to interact with the backend. The contents of the` .env` file are as follows:
```
# Proxy interface address (modified by yourself)
API_BASE = http://192.168.xx.xx:12345
@@ -67,7 +67,7 @@ Visit address` http://localhost:8888/#/`
Install pm2 `npm install -g pm2`
-Execute `pm2 start npm -- run dev` to start the project in the project `escheduler-ui `root directory
+Execute `pm2 start npm -- run dev` to start the project in the project `dolphinscheduler-ui `root directory
#### command
@@ -81,7 +81,7 @@ Execute `pm2 start npm -- run dev` to start the project in the project `eschedul
```
-[root@localhost escheduler-ui]# pm2 start npm -- run dev
+[root@localhost dolphinscheduler-ui]# pm2 start npm -- run dev
[PM2] Applying action restartProcessId on app [npm](ids: 0)
[PM2] [npm](0) ✓
[PM2] Process successfully started
diff --git a/docs/en_US/quick-start.md b/docs/en_US/quick-start.md
index a1dc255345..b4dce0ea5f 100644
--- a/docs/en_US/quick-start.md
+++ b/docs/en_US/quick-start.md
@@ -2,7 +2,7 @@
* Administrator user login
- > Address:192.168.xx.xx:8888 Username and password:admin/escheduler123
+ > Address:192.168.xx.xx:8888 Username and password:admin/dolphinscheduler123
diff --git a/docs/en_US/system-manual.md b/docs/en_US/system-manual.md
index d571e1d66f..751420c2d4 100644
--- a/docs/en_US/system-manual.md
+++ b/docs/en_US/system-manual.md
@@ -331,7 +331,7 @@ conf/common/hadoop.properties
## Security
- The security has the functions of queue management, tenant management, user management, warning group management, worker group manager, token manage and other functions. It can also authorize resources, data sources, projects, etc.
-- Administrator login, default username password: admin/escheduler 123
+- Administrator login, default username password: admin/dolphinscheduler123
@@ -391,7 +391,7 @@ conf/common/hadoop.properties
CloseableHttpClient httpclient = HttpClients.createDefault();
// create http post request
- HttpPost httpPost = new HttpPost("http://127.0.0.1:12345/escheduler/projects/create");
+ HttpPost httpPost = new HttpPost("http://127.0.0.1:12345/dolphinscheduler/projects/create");
httpPost.setHeader("token", "123");
// set parameters
List parameters = new ArrayList();
diff --git a/docs/en_US/upgrade.md b/docs/en_US/upgrade.md
index b5c743fd84..28af7d0703 100644
--- a/docs/en_US/upgrade.md
+++ b/docs/en_US/upgrade.md
@@ -3,13 +3,13 @@
## 1. Back up the previous version of the files and database
-## 2. Stop all services of escheduler
+## 2. Stop all services of dolphinscheduler
`sh ./script/stop-all.sh`
## 3. Download the new version of the installation package
-- [gitee](https://gitee.com/easyscheduler/EasyScheduler/attach_files), download the latest version of the front and back installation packages (backend referred to as escheduler-backend, front end referred to as escheduler-ui)
+- [gitee](https://gitee.com/easyscheduler/EasyScheduler/attach_files), download the latest version of the front and back installation packages (backend referred to as dolphinscheduler-backend, front end referred to as dolphinscheduler-ui)
- The following upgrade operations need to be performed in the new version of the directory
## 4. Database upgrade
@@ -23,7 +23,7 @@
- Execute database upgrade script
-`sh ./script/upgrade-escheduler.sh`
+`sh ./script/upgrade-dolphinscheduler.sh`
## 5. Backend service upgrade
diff --git a/docs/zh_CN/EasyScheduler-FAQ.md b/docs/zh_CN/EasyScheduler-FAQ.md
index 360565a4ee..a4419a4c00 100644
--- a/docs/zh_CN/EasyScheduler-FAQ.md
+++ b/docs/zh_CN/EasyScheduler-FAQ.md
@@ -50,7 +50,7 @@ A:我们同时 **支持流程和任务的优先级**。优先级我们有 **HI
----
-## Q:escheduler-grpc报错
+## Q:dolphinscheduler-grpc报错
A:在根目录下执行:mvn -U clean package assembly:assembly -Dmaven.test.skip=true , 然后刷新下整个项目
@@ -70,11 +70,11 @@ A:单独安装 **npm install node-sass --unsafe-perm**,之后再 **npm insta
## Q:UI 不能正常登陆访问
-A: 1,如果是node启动的查看escheduler-ui下的.env API_BASE配置是否是Api Server服务地址
+A: 1,如果是node启动的查看dolphinscheduler-ui下的.env API_BASE配置是否是Api Server服务地址
- 2,如果是nginx启动的并且是通过 **install-escheduler-ui.sh** 安装的,查看 **/etc/nginx/conf.d/escheduler.conf** 中的proxy_pass配置是否是Api Server服务地址
+ 2,如果是nginx启动的并且是通过 **install-dolphinscheduler-ui.sh** 安装的,查看 **/etc/nginx/conf.d/dolphinscheduler.conf** 中的proxy_pass配置是否是Api Server服务地址
- 3,如果以上配置都是正确的,那么请查看Api Server服务是否是正常的,curl http://192.168.xx.xx:12345/escheduler/users/get-user-info,查看Api Server日志,如果提示 cn.escheduler.api.interceptor.LoginHandlerInterceptor:[76] - session info is null,则证明Api Server服务是正常的
+ 3,如果以上配置都是正确的,那么请查看Api Server服务是否是正常的,curl http://192.168.xx.xx:12345/dolphinscheduler/users/get-user-info,查看Api Server日志,如果提示 cn.dolphinscheduler.api.interceptor.LoginHandlerInterceptor:[76] - session info is null,则证明Api Server服务是正常的
4,如果以上都没有问题,需要查看一下 **application.properties** 中的 **server.context-path 和 server.port 配置**是否正确
@@ -84,7 +84,7 @@ A: 1,如果是node启动的查看escheduler-ui下的.env API_BASE配置是
A: 1,首先通过**jps 查看MasterServer服务是否存在**,或者从服务监控直接查看zk中是否存在master服务
- 2,如果存在master服务,查看 **命令状态统计** 或者 **t_escheduler_error_command** 中是否增加的新记录,如果增加了,**请查看 message 字段定位启动异常原因**
+ 2,如果存在master服务,查看 **命令状态统计** 或者 **t_dolphinscheduler_error_command** 中是否增加的新记录,如果增加了,**请查看 message 字段定位启动异常原因**
---
@@ -102,9 +102,9 @@ A: 1,首先通过**jps 查看WorkerServer服务是否存在**,或者从服
A: 提供Docker镜像及Dockerfile。
-Docker镜像地址:https://hub.docker.com/r/escheduler/escheduler_images
+Docker镜像地址:https://hub.docker.com/r/dolphinscheduler/dolphinscheduler_images
-Dockerfile地址:https://github.com/qiaozhanwei/escheduler_dockerfile/tree/master/docker_escheduler
+Dockerfile地址:https://github.com/qiaozhanwei/dolphinscheduler_dockerfile/tree/master/docker_dolphinscheduler
---
@@ -112,9 +112,9 @@ Dockerfile地址:https://github.com/qiaozhanwei/escheduler_dockerfile/tree/mas
A: 1,如果替换变量中包含特殊字符,**请用 \ 转移符进行转移**
- 2,installPath="/data1_1T/escheduler",**这个目录不能和当前要一键安装的install.sh目录是一样的**
+ 2,installPath="/data1_1T/dolphinscheduler",**这个目录不能和当前要一键安装的install.sh目录是一样的**
- 3,deployUser="escheduler",**部署用户必须具有sudo权限**,因为worker是通过sudo -u 租户 sh xxx.command进行执行的
+ 3,deployUser="dolphinscheduler",**部署用户必须具有sudo权限**,因为worker是通过sudo -u 租户 sh xxx.command进行执行的
4,monitorServerState="false",服务监控脚本是否启动,默认是不启动服务监控脚本的。**如果启动服务监控脚本,则每5分钟定时来监控master和worker的服务是否down机,如果down机则会自动重启**
@@ -126,7 +126,7 @@ A: 1,如果替换变量中包含特殊字符,**请用 \ 转移符进行
## Q : 流程定义和流程实例下线异常
-A : 对于 **1.0.4 以前的版本中**,修改escheduler-api cn.escheduler.api.quartz包下的代码即可
+A : 对于 **1.0.4 以前的版本中**,修改dolphinscheduler-api cn.dolphinscheduler.api.quartz包下的代码即可
```
public boolean deleteJob(String jobName, String jobGroupName) {
@@ -205,7 +205,7 @@ A: 1,在 **流程定义列表**,点击 **启动** 按钮
## Q : Python任务设置Python版本
-A: 1,对于1**.0.3之后的版本**只需要修改 conf/env/.escheduler_env.sh中的PYTHON_HOME
+A: 1,对于1**.0.3之后的版本**只需要修改 conf/env/.dolphinscheduler_env.sh中的PYTHON_HOME
```
export PYTHON_HOME=/bin/python
diff --git a/docs/zh_CN/SUMMARY.md b/docs/zh_CN/SUMMARY.md
index 2b153b60c5..06d17b9215 100644
--- a/docs/zh_CN/SUMMARY.md
+++ b/docs/zh_CN/SUMMARY.md
@@ -29,7 +29,7 @@
* [开发环境搭建](后端开发文档.md#项目编译)
* [自定义任务插件文档](任务插件开发.md#任务插件开发)
-* [接口文档](http://52.82.13.76:8888/escheduler/doc.html?language=zh_CN&lang=cn)
+* [接口文档](http://52.82.13.76:8888/dolphinscheduler/doc.html?language=zh_CN&lang=cn)
* FAQ
* [FAQ](EasyScheduler-FAQ.md)
* 系统版本升级文档
diff --git a/docs/zh_CN/任务插件开发.md b/docs/zh_CN/任务插件开发.md
index 5e733b9540..0157735974 100644
--- a/docs/zh_CN/任务插件开发.md
+++ b/docs/zh_CN/任务插件开发.md
@@ -6,8 +6,8 @@
#### 基于YARN的计算(参见MapReduceTask)
-- 需要在 **cn.escheduler.server.worker.task** 下的 **TaskManager** 类中创建自定义任务(也需在TaskType注册对应的任务类型)
-- 需要继承**cn.escheduler.server.worker.task** 下的 **AbstractYarnTask**
+- 需要在 **org.apache.dolphinscheduler.server.worker.task** 下的 **TaskManager** 类中创建自定义任务(也需在TaskType注册对应的任务类型)
+- 需要继承**org.apache.dolphinscheduler.server.worker.task** 下的 **AbstractYarnTask**
- 构造方法调度 **AbstractYarnTask** 构造方法
- 继承 **AbstractParameters** 自定义任务参数实体
- 重写 **AbstractTask** 的 **init** 方法中解析**自定义任务参数**
@@ -16,9 +16,9 @@
#### 基于非YARN的计算(参见ShellTask)
-- 需要在 **cn.escheduler.server.worker.task** 下的 **TaskManager** 中创建自定义任务
+- 需要在 **org.apache.dolphinscheduler.server.worker.task** 下的 **TaskManager** 中创建自定义任务
-- 需要继承**cn.escheduler.server.worker.task** 下的 **AbstractTask**
+- 需要继承**org.apache.dolphinscheduler.server.worker.task** 下的 **AbstractTask**
- 构造方法中实例化 **ShellCommandExecutor**
@@ -46,8 +46,8 @@
### 基于非SHELL的任务(参见SqlTask)
-- 需要在 **cn.escheduler.server.worker.task** 下的 **TaskManager** 中创建自定义任务
-- 需要继承**cn.escheduler.server.worker.task** 下的 **AbstractTask**
+- 需要在 **org.apache.dolphinscheduler.server.worker.task** 下的 **TaskManager** 中创建自定义任务
+- 需要继承**org.apache.dolphinscheduler.server.worker.task** 下的 **AbstractTask**
- 继承 **AbstractParameters** 自定义任务参数实体
- 构造方法或者重写 **AbstractTask** 的 **init** 方法中,解析自定义任务参数实体
- 重写 **handle** 方法实现业务逻辑并设置相应的**exitStatusCode**
diff --git a/docs/zh_CN/前端开发文档.md b/docs/zh_CN/前端开发文档.md
index f805f5ed8c..4d5cea11f3 100644
--- a/docs/zh_CN/前端开发文档.md
+++ b/docs/zh_CN/前端开发文档.md
@@ -23,7 +23,7 @@ Node包下载 (注意版本 8.9.4) `https://nodejs.org/download/release/v8.9.4/`
- #### 前端项目构建
-用命令行模式 `cd` 进入 `escheduler-ui`项目目录并执行 `npm install` 拉取项目依赖包
+用命令行模式 `cd` 进入 `dolphinscheduler-ui`项目目录并执行 `npm install` 拉取项目依赖包
> 如果 `npm install` 速度非常慢
@@ -34,7 +34,7 @@ Node包下载 (注意版本 8.9.4) `https://nodejs.org/download/release/v8.9.4/`
- 新建一个`.env`文件,用于跟后端交互的接口
-在`escheduler-ui`目录下新建一个`.env`文件,在文件里添加后端服务的ip地址和端口,用于跟后端交互,`.env`文件内容如下:
+在`dolphinscheduler-ui`目录下新建一个`.env`文件,在文件里添加后端服务的ip地址和端口,用于跟后端交互,`.env`文件内容如下:
```
# 代理的接口地址(自行修改)
API_BASE = http://192.168.xx.xx:12345
@@ -68,7 +68,7 @@ npm install node-sass --unsafe-perm //单独安装node-sass依赖
安装pm2 `npm install -g pm2`
-在项目`escheduler-ui`根目录执行 `pm2 start npm -- run dev` 启动项目
+在项目`dolphinscheduler-ui`根目录执行 `pm2 start npm -- run dev` 启动项目
#### 命令
@@ -82,7 +82,7 @@ npm install node-sass --unsafe-perm //单独安装node-sass依赖
```
-[root@localhost escheduler-ui]# pm2 start npm -- run dev
+[root@localhost dolphinscheduler-ui]# pm2 start npm -- run dev
[PM2] Applying action restartProcessId on app [npm](ids: 0)
[PM2] [npm](0) ✓
[PM2] Process successfully started
diff --git a/docs/zh_CN/前端部署文档.md b/docs/zh_CN/前端部署文档.md
index dc9cf61216..8bb7324531 100644
--- a/docs/zh_CN/前端部署文档.md
+++ b/docs/zh_CN/前端部署文档.md
@@ -7,7 +7,7 @@
请下载最新版本的安装包,下载地址: [码云下载](https://gitee.com/easyscheduler/EasyScheduler/attach_files/) 或者 [github下载](https://github.com/analysys/EasyScheduler/releases)
-下载 escheduler-ui-x.x.x.tar.gz 后,解压`tar -zxvf escheduler-ui-x.x.x.tar.gz ./`后,进入`escheduler-ui`目录
+下载 dolphinscheduler-ui-x.x.x.tar.gz 后,解压`tar -zxvf dolphinscheduler-ui-x.x.x.tar.gz ./`后,进入`dolphinscheduler-ui`目录
@@ -16,7 +16,7 @@
以下两种方式任选其一部署即可,推荐自动化部署
### 2.1 自动化部署
-在`escheduler-ui`目录下编辑安装文件`vi install-escheduler-ui.sh`
+在`dolphinscheduler-ui`目录下编辑安装文件`vi install-dolphinscheduler-ui.sh`
更改前端访问端口和后端代理接口地址
@@ -30,7 +30,7 @@ esc_proxy_port="http://192.168.xx.xx:12345"
>前端自动部署基于linux系统`yum`操作,部署之前请先安装更新`yum`
-在该目录下执行`./install-escheduler-ui.sh`
+在该目录下执行`./install-dolphinscheduler-ui.sh`
### 2.2 手动部署
@@ -55,7 +55,7 @@ server {
root /xx/dist; # 上面前端解压的dist目录地址(自行修改)
index index.html index.html;
}
- location /escheduler {
+ location /dolphinscheduler {
proxy_pass http://192.168.xx.xx:12345; # 接口地址(自行修改)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
diff --git a/docs/zh_CN/升级文档.md b/docs/zh_CN/升级文档.md
index 83166971fc..b2d9c29cfe 100644
--- a/docs/zh_CN/升级文档.md
+++ b/docs/zh_CN/升级文档.md
@@ -3,13 +3,13 @@
## 1. 备份上一版本文件和数据库
-## 2. 停止escheduler所有服务
+## 2. 停止dolphinscheduler所有服务
`sh ./script/stop-all.sh`
## 3. 下载新版本的安装包
-- [码云下载](https://gitee.com/easyscheduler/EasyScheduler/attach_files), 下载最新版本的前后端安装包(后端简称escheduler-backend、前端简称escheduler-ui)
+- [码云下载](https://gitee.com/easyscheduler/EasyScheduler/attach_files), 下载最新版本的前后端安装包(后端简称dolphinscheduler-backend、前端简称dolphinscheduler-ui)
- 以下升级操作都需要在新版本的目录进行
## 4. 数据库升级
@@ -23,7 +23,7 @@
- 执行数据库升级脚本
-`sh ./script/upgrade-escheduler.sh`
+`sh ./script/upgrade-dolphinscheduler.sh`
## 5. 后端服务升级
diff --git a/docs/zh_CN/后端开发文档.md b/docs/zh_CN/后端开发文档.md
index 7d2d34a0a0..6159f85c0a 100644
--- a/docs/zh_CN/后端开发文档.md
+++ b/docs/zh_CN/后端开发文档.md
@@ -7,7 +7,7 @@
* [ZooKeeper](https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper)(3.4.6+) :必装
* [Maven](http://maven.apache.org/download.cgi)(3.3+) :必装
-因EasyScheduler中escheduler-rpc模块使用到Grpc,需要用到Maven编译生成所需要的类
+因EasyScheduler中dolphinscheduler-rpc模块使用到Grpc,需要用到Maven编译生成所需要的类
对maven不熟的伙伴请参考: [maven in five minutes](http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html)(3.3+)
http://maven.apache.org/install.html
@@ -23,7 +23,7 @@ http://maven.apache.org/install.html
* 查看目录
-正常编译完后,会在当前目录生成 ./target/escheduler-{version}/
+正常编译完后,会在当前目录生成 ./target/dolphinscheduler-{version}/
```
bin
diff --git a/docs/zh_CN/后端部署文档.md b/docs/zh_CN/后端部署文档.md
index bf217880a5..525b0e7f8a 100644
--- a/docs/zh_CN/后端部署文档.md
+++ b/docs/zh_CN/后端部署文档.md
@@ -4,7 +4,7 @@
## 1、准备工作
-请下载最新版本的安装包,下载地址: [码云下载](https://gitee.com/easyscheduler/EasyScheduler/attach_files/)或者[github下载](https://github.com/analysys/EasyScheduler/releases) ,下载escheduler-backend-x.x.x.tar.gz(后端简称escheduler-backend),escheduler-ui-x.x.x.tar.gz(前端简称escheduler-ui)
+请下载最新版本的安装包,下载地址: [码云下载](https://gitee.com/easyscheduler/EasyScheduler/attach_files/)或者[github下载](https://github.com/apache/incubator-dolphinscheduler/releases) ,下载dolphinscheduler-backend-x.x.x.tar.gz(后端简称dolphinscheduler-backend),dolphinscheduler-ui-x.x.x.tar.gz(前端简称dolphinscheduler-ui)
#### 准备一: 基础软件安装(必装项请自行安装)
@@ -27,8 +27,8 @@
```部署账号
vi /etc/sudoers
-# 例如部署用户是escheduler账号
-escheduler ALL=(ALL) NOPASSWD: NOPASSWD: ALL
+# 例如部署用户是dolphinscheduler账号
+dolphinscheduler ALL=(ALL) NOPASSWD: NOPASSWD: ALL
# 并且需要注释掉 Default requiretty 一行
#Default requiretty
@@ -47,9 +47,9 @@ escheduler ALL=(ALL) NOPASSWD: NOPASSWD: ALL
执行以下命令创建database和账号
```sql
- CREATE DATABASE escheduler DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
- GRANT ALL PRIVILEGES ON escheduler.* TO '{user}'@'%' IDENTIFIED BY '{password}';
- GRANT ALL PRIVILEGES ON escheduler.* TO '{user}'@'localhost' IDENTIFIED BY '{password}';
+ CREATE DATABASE dolphinscheduler DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
+ GRANT ALL PRIVILEGES ON dolphinscheduler.* TO '{user}'@'%' IDENTIFIED BY '{password}';
+ GRANT ALL PRIVILEGES ON dolphinscheduler.* TO '{user}'@'localhost' IDENTIFIED BY '{password}';
flush privileges;
```
@@ -63,12 +63,12 @@ escheduler ALL=(ALL) NOPASSWD: NOPASSWD: ALL
```
执行创建表和导入基础数据脚本
```
- sh ./script/create-escheduler.sh
+ sh ./script/create-dolphinscheduler.sh
```
#### 准备五: 修改部署目录权限及运行参数
- escheduler-backend目录介绍
+ dolphinscheduler-backend目录介绍
```
bin : 基础服务启动脚本
@@ -79,11 +79,11 @@ sql : 项目依赖sql文件
install.sh : 一键部署脚本
```
-- 修改权限(请将'deployUser'字段修改为对应部署用户),使得部署用户对escheduler-backend目录有操作权限
+- 修改权限(请将'deployUser'字段修改为对应部署用户),使得部署用户对dolphinscheduler-backend目录有操作权限
- `sudo chown -R deployUser:deployUser escheduler-backend`
+ `sudo chown -R deployUser:deployUser dolphinscheduler-backend`
-- 修改conf/env/目录下的 `.escheduler_env.sh` 环境变量
+- 修改conf/env/目录下的 `.dolphinscheduler_env.sh` 环境变量
- 修改部署参数(根据自己服务器及业务情况):
@@ -127,11 +127,11 @@ install.sh : 一键部署脚本
```日志路径
logs/
- ├── escheduler-alert-server.log
- ├── escheduler-master-server.log
- |—— escheduler-worker-server.log
- |—— escheduler-api-server.log
- |—— escheduler-logger-server.log
+ ├── dolphinscheduler-alert-server.log
+ ├── dolphinscheduler-master-server.log
+ |—— dolphinscheduler-worker-server.log
+ |—— dolphinscheduler-api-server.log
+ |—— dolphinscheduler-logger-server.log
```
### 2.2 编译源码来部署
@@ -146,7 +146,7 @@ install.sh : 一键部署脚本
* 查看目录
-正常编译完后,会在当前目录生成 `./target/escheduler-{version}/`
+正常编译完后,会在当前目录生成 `./target/dolphinscheduler-{version}/`
```查看目录
../
@@ -173,38 +173,38 @@ install.sh : 一键部署脚本
* 启停Master
```启动master
-sh ./bin/escheduler-daemon.sh start master-server
-sh ./bin/escheduler-daemon.sh stop master-server
+sh ./bin/dolphinscheduler-daemon.sh start master-server
+sh ./bin/dolphinscheduler-daemon.sh stop master-server
```
* 启停Worker
```
-sh ./bin/escheduler-daemon.sh start worker-server
-sh ./bin/escheduler-daemon.sh stop worker-server
+sh ./bin/dolphinscheduler-daemon.sh start worker-server
+sh ./bin/dolphinscheduler-daemon.sh stop worker-server
```
* 启停Api
```
-sh ./bin/escheduler-daemon.sh start api-server
-sh ./bin/escheduler-daemon.sh stop api-server
+sh ./bin/dolphinscheduler-daemon.sh start api-server
+sh ./bin/dolphinscheduler-daemon.sh stop api-server
```
* 启停Logger
```
-sh ./bin/escheduler-daemon.sh start logger-server
-sh ./bin/escheduler-daemon.sh stop logger-server
+sh ./bin/dolphinscheduler-daemon.sh start logger-server
+sh ./bin/dolphinscheduler-daemon.sh stop logger-server
```
* 启停Alert
```
-sh ./bin/escheduler-daemon.sh start alert-server
-sh ./bin/escheduler-daemon.sh stop alert-server
+sh ./bin/dolphinscheduler-daemon.sh start alert-server
+sh ./bin/dolphinscheduler-daemon.sh stop alert-server
```
## 3、数据库升级
数据库升级是在1.0.2版本增加的功能,执行以下命令即可自动升级数据库
```
-sh ./script/upgrade-escheduler.sh
+sh ./script/upgrade-dolphinscheduler.sh
```
diff --git a/docs/zh_CN/快速上手.md b/docs/zh_CN/快速上手.md
index 966ef88e84..7aa4f6577c 100644
--- a/docs/zh_CN/快速上手.md
+++ b/docs/zh_CN/快速上手.md
@@ -1,7 +1,7 @@
# 快速上手
* 管理员用户登录
- >地址:192.168.xx.xx:8888 用户名密码:admin/escheduler123
+ >地址:192.168.xx.xx:8888 用户名密码:admin/dolphinscheduler123
diff --git a/docs/zh_CN/系统使用手册.md b/docs/zh_CN/系统使用手册.md
index 348cc2b36a..8ec5d0a5ea 100644
--- a/docs/zh_CN/系统使用手册.md
+++ b/docs/zh_CN/系统使用手册.md
@@ -323,7 +323,7 @@ conf/common/hadoop.properties
## 安全中心(权限系统)
- 安全中心是只有管理员账户才有权限的功能,有队列管理、租户管理、用户管理、告警组管理、worker分组、令牌管理等功能,还可以对资源、数据源、项目等授权
- - 管理员登录,默认用户名密码:admin/escheduler123
+ - 管理员登录,默认用户名密码:admin/dolphinscheduler123
### 创建队列
- 队列是在执行spark、mapreduce等程序,需要用到“队列”参数时使用的。
@@ -379,7 +379,7 @@ conf/common/hadoop.properties
CloseableHttpClient httpclient = HttpClients.createDefault();
// create http post request
- HttpPost httpPost = new HttpPost("http://127.0.0.1:12345/escheduler/projects/create");
+ HttpPost httpPost = new HttpPost("http://127.0.0.1:12345/dolphinscheduler/projects/create");
httpPost.setHeader("token", "123");
// set parameters
List parameters = new ArrayList();
diff --git a/dolphinscheduler-alert/pom.xml b/dolphinscheduler-alert/pom.xml
new file mode 100644
index 0000000000..11dc7bd960
--- /dev/null
+++ b/dolphinscheduler-alert/pom.xml
@@ -0,0 +1,129 @@
+
+
+ 4.0.0
+
+ org.apache.dolphinscheduler
+ dolphinscheduler
+ 1.1.0-SNAPSHOT
+
+ dolphinscheduler-alert
+ jar
+
+
+ UTF-8
+
+
+
+ junit
+ junit
+ test
+
+
+
+ org.apache.commons
+ commons-email
+
+
+
+ org.freemarker
+ freemarker
+
+
+
+ com.alibaba
+ fastjson
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+ org.apache.commons
+ commons-collections4
+
+
+
+ commons-logging
+ commons-logging
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+ com.google.guava
+ guava
+
+
+
+ ch.qos.logback
+ logback-classic
+
+
+
+ commons-io
+ commons-io
+
+
+
+
+
+ org.apache.poi
+ poi
+
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-dao
+
+
+
+
+
+
+
+ maven-assembly-plugin
+ 2.6
+
+
+ src/main/assembly/package.xml
+
+ false
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+
+
+
diff --git a/dolphinscheduler-alert/src/main/assembly/package.xml b/dolphinscheduler-alert/src/main/assembly/package.xml
new file mode 100644
index 0000000000..b10f76c62b
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/assembly/package.xml
@@ -0,0 +1,40 @@
+
+ cluster
+
+ dir
+
+ false
+
+
+ src/main/resources
+
+ **/*.properties
+ **/*.xml
+ **/*.json
+ **/*.ftl
+
+ conf
+
+
+ target/
+
+ dolphinscheduler-alert-${project.version}.jar
+
+ lib
+
+
+
+
+ lib
+ true
+
+ javax.servlet:servlet-api
+ org.eclipse.jetty.aggregate:jetty-all
+ org.slf4j:slf4j-log4j12
+
+
+
+
\ No newline at end of file
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java
new file mode 100644
index 0000000000..3eba9fdbc8
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert;
+
+import org.apache.dolphinscheduler.alert.runner.AlertSender;
+import org.apache.dolphinscheduler.alert.utils.Constants;
+import org.apache.dolphinscheduler.common.thread.Stopper;
+import org.apache.dolphinscheduler.dao.AlertDao;
+import org.apache.dolphinscheduler.dao.entity.Alert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.List;
+
+/**
+ * alert of start
+ */
+@ComponentScan("cn.escheduler")
+public class AlertServer implements CommandLineRunner {
+ private static final Logger logger = LoggerFactory.getLogger(AlertServer.class);
+ /**
+ * Alert Dao
+ */
+ @Autowired
+ private AlertDao alertDao;
+
+ private AlertSender alertSender;
+
+ private static volatile AlertServer instance;
+
+ public AlertServer() {
+
+ }
+
+ public static AlertServer getInstance(){
+ if (null == instance) {
+ synchronized (AlertServer.class) {
+ if(null == instance) {
+ instance = new AlertServer();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public void start(){
+ logger.info("Alert Server ready start!");
+ while (Stopper.isRunning()){
+ try {
+ Thread.sleep(Constants.ALERT_SCAN_INTERVEL);
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(),e);
+ }
+ List alerts = alertDao.listWaitExecutionAlert();
+ alertSender = new AlertSender(alerts, alertDao);
+ alertSender.run();
+ }
+ }
+
+
+ public static void main(String[] args){
+ SpringApplication app = new SpringApplication(AlertServer.class);
+ app.run(args);
+ }
+
+ @Override
+ public void run(String... strings) throws Exception {
+ AlertServer alertServer = AlertServer.getInstance();
+ alertServer.start();
+ }
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java
new file mode 100644
index 0000000000..957f195e1c
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.manager;
+
+import org.apache.dolphinscheduler.alert.utils.MailUtils;
+import org.apache.dolphinscheduler.common.enums.ShowType;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * email send manager
+ */
+public class EmailManager {
+ /**
+ * email send
+ * @param receviersList
+ * @param receviersCcList
+ * @param title
+ * @param content
+ * @param showType
+ * @return
+ */
+ public Map send(List receviersList,List receviersCcList,String title,String content,ShowType showType){
+
+ return MailUtils.sendMails(receviersList, receviersCcList, title, content, showType);
+ }
+
+ /**
+ * msg send
+ * @param receviersList
+ * @param title
+ * @param content
+ * @param showType
+ * @return
+ */
+ public Map send(List receviersList,String title,String content,ShowType showType){
+
+ return MailUtils.sendMails(receviersList,title, content, showType);
+ }
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java
new file mode 100644
index 0000000000..67f4fee7e0
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.manager;
+
+import org.apache.dolphinscheduler.alert.utils.Constants;
+import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils;
+import org.apache.dolphinscheduler.dao.entity.Alert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Enterprise WeChat Manager
+ */
+public class EnterpriseWeChatManager {
+ private static final Logger logger = LoggerFactory.getLogger(MsgManager.class);
+ /**
+ * Enterprise We Chat send
+ * @param alert
+ */
+ public Map send(Alert alert, String token){
+ Map retMap = new HashMap<>();
+ retMap.put(Constants.STATUS, false);
+ String agentId = EnterpriseWeChatUtils.enterpriseWeChatAgentId;
+ String users = EnterpriseWeChatUtils.enterpriseWeChatUsers;
+ List userList = Arrays.asList(users.split(","));
+ logger.info("send message {}",alert);
+ String msg = EnterpriseWeChatUtils.makeUserSendMsg(userList, agentId,EnterpriseWeChatUtils.markdownByAlert(alert));
+ try {
+ EnterpriseWeChatUtils.sendEnterpriseWeChat(Constants.UTF_8, msg, token);
+ } catch (IOException e) {
+ logger.error(e.getMessage(),e);
+ }
+ retMap.put(Constants.STATUS, true);
+ return retMap;
+ }
+
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/MsgManager.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/MsgManager.java
new file mode 100644
index 0000000000..35cc9bea3f
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/MsgManager.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.manager;
+
+import org.apache.dolphinscheduler.dao.entity.Alert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SMS send manager
+ */
+public class MsgManager {
+
+ private static final Logger logger = LoggerFactory.getLogger(MsgManager.class);
+ /**
+ * SMS send
+ * @param alert
+ */
+ public void send(Alert alert){
+ logger.info("send message {}",alert);
+ }
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java
new file mode 100644
index 0000000000..f7d73e0d77
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.runner;
+
+import org.apache.dolphinscheduler.alert.manager.EmailManager;
+import org.apache.dolphinscheduler.alert.manager.EnterpriseWeChatManager;
+import org.apache.dolphinscheduler.alert.utils.Constants;
+import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils;
+import org.apache.dolphinscheduler.common.enums.AlertStatus;
+import org.apache.dolphinscheduler.common.enums.AlertType;
+import org.apache.dolphinscheduler.dao.AlertDao;
+import org.apache.dolphinscheduler.dao.entity.Alert;
+import org.apache.dolphinscheduler.dao.entity.User;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * alert sender
+ */
+public class AlertSender{
+
+ private static final Logger logger = LoggerFactory.getLogger(AlertSender.class);
+
+ private static final EmailManager emailManager= new EmailManager();
+ private static final EnterpriseWeChatManager weChatManager= new EnterpriseWeChatManager();
+
+
+ private List alertList;
+ private AlertDao alertDao;
+
+ public AlertSender(){}
+ public AlertSender(List alertList, AlertDao alertDao){
+ super();
+ this.alertList = alertList;
+ this.alertDao = alertDao;
+ }
+
+ public void run() {
+
+ List users;
+
+ Map retMaps = null;
+ for(Alert alert:alertList){
+ users = alertDao.listUserByAlertgroupId(alert.getAlertGroupId());
+
+
+
+ // receiving group list
+ List receviersList = new ArrayList();
+ for(User user:users){
+ receviersList.add(user.getEmail());
+ }
+ // custom receiver
+ String receivers = alert.getReceivers();
+ if (StringUtils.isNotEmpty(receivers)){
+ String[] splits = receivers.split(",");
+ for (String receiver : splits){
+ receviersList.add(receiver);
+ }
+ }
+
+ // copy list
+ List receviersCcList = new ArrayList();
+
+
+ // Custom Copier
+ String receiversCc = alert.getReceiversCc();
+
+ if (StringUtils.isNotEmpty(receiversCc)){
+ String[] splits = receiversCc.split(",");
+ for (String receiverCc : splits){
+ receviersCcList.add(receiverCc);
+ }
+ }
+
+ if (CollectionUtils.isEmpty(receviersList) && CollectionUtils.isEmpty(receviersCcList)) {
+ logger.warn("alert send error : At least one receiver address required");
+ alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE, "execution failure,At least one receiver address required.", alert.getId());
+ continue;
+ }
+
+ if (alert.getAlertType() == AlertType.EMAIL){
+ retMaps = emailManager.send(receviersList,receviersCcList, alert.getTitle(), alert.getContent(),alert.getShowType());
+
+ alert.setInfo(retMaps);
+ }else if (alert.getAlertType() == AlertType.SMS){
+ retMaps = emailManager.send(getReciversForSMS(users), alert.getTitle(), alert.getContent(),alert.getShowType());
+ alert.setInfo(retMaps);
+ }
+
+ boolean flag = Boolean.parseBoolean(String.valueOf(retMaps.get(Constants.STATUS)));
+ if (flag){
+ alertDao.updateAlert(AlertStatus.EXECUTION_SUCCESS, "execution success", alert.getId());
+ logger.info("alert send success");
+ try {
+ String token = EnterpriseWeChatUtils.getToken();
+ weChatManager.send(alert,token);
+ } catch (Exception e) {
+ logger.error(e.getMessage(),e);
+ }
+ }else {
+ alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE,String.valueOf(retMaps.get(Constants.MESSAGE)),alert.getId());
+ logger.info("alert send error : {}" , String.valueOf(retMaps.get(Constants.MESSAGE)));
+ }
+ }
+
+ }
+
+
+ /**
+ * get a list of SMS users
+ * @param users
+ * @return
+ */
+ private List getReciversForSMS(List users){
+ List list = new ArrayList<>();
+ for (User user : users){
+ list.add(user.getPhone());
+ }
+ return list;
+ }
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java
new file mode 100644
index 0000000000..0a35d85fc4
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+/**
+ * constants
+ */
+public class Constants {
+
+ /**
+ * alert properties path
+ */
+ public static final String ALERT_PROPERTIES_PATH = "/alert.properties";
+
+ public static final String DATA_SOURCE_PROPERTIES_PATH = "/dao/data_source.properties__";
+
+ public static final String SINGLE_SLASH = "/";
+
+ /**
+ * UTF-8
+ */
+ public static final String UTF_8 = "UTF-8";
+
+ public static final String STATUS = "status";
+
+ public static final String MESSAGE = "message";
+
+ public static final String MAIL_PROTOCOL = "mail.protocol";
+
+ public static final String MAIL_SERVER_HOST = "mail.server.host";
+
+ public static final String MAIL_SERVER_PORT = "mail.server.port";
+
+ public static final String MAIL_SENDER = "mail.sender";
+
+ public static final String MAIL_USER = "mail.user";
+
+ public static final String MAIL_PASSWD = "mail.passwd";
+
+ public static final String XLS_FILE_PATH = "xls.file.path";
+
+ public static final String MAIL_HOST = "mail.smtp.host";
+
+ public static final String MAIL_PORT = "mail.smtp.port";
+
+ public static final String MAIL_SMTP_AUTH = "mail.smtp.auth";
+
+ public static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol";
+
+ public static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable";
+
+ public static final String MAIL_SMTP_SSL_ENABLE = "mail.smtp.ssl.enable";
+
+ public static final String MAIL_SMTP_SSL_TRUST="mail.smtp.ssl.trust";
+
+ public static final String TEXT_HTML_CHARSET_UTF_8 = "text/html;charset=utf-8";
+
+ public static final String STRING_TRUE = "true";
+
+ public static final String EXCEL_SUFFIX_XLS = ".xls";
+
+ public static final int NUMBER_1000 = 1000;
+
+ public static final String SPRING_DATASOURCE_DRIVER_CLASS_NAME = "spring.datasource.driver-class-name";
+
+ public static final String SPRING_DATASOURCE_URL = "spring.datasource.url";
+
+ public static final String SPRING_DATASOURCE_USERNAME = "spring.datasource.username";
+
+ public static final String SPRING_DATASOURCE_PASSWORD = "spring.datasource.password";
+
+ public static final String SPRING_DATASOURCE_VALIDATION_QUERY_TIMEOUT = "spring.datasource.validationQueryTimeout";
+
+ public static final String SPRING_DATASOURCE_INITIAL_SIZE = "spring.datasource.initialSize";
+
+ public static final String SPRING_DATASOURCE_MIN_IDLE = "spring.datasource.minIdle";
+
+ public static final String SPRING_DATASOURCE_MAX_ACTIVE = "spring.datasource.maxActive";
+
+ public static final String SPRING_DATASOURCE_MAX_WAIT = "spring.datasource.maxWait";
+
+ public static final String SPRING_DATASOURCE_TIME_BETWEEN_EVICTION_RUNS_MILLIS = "spring.datasource.timeBetweenEvictionRunsMillis";
+
+ public static final String SPRING_DATASOURCE_MIN_EVICTABLE_IDLE_TIME_MILLIS = "spring.datasource.minEvictableIdleTimeMillis";
+
+ public static final String SPRING_DATASOURCE_VALIDATION_QUERY = "spring.datasource.validationQuery";
+
+ public static final String SPRING_DATASOURCE_TEST_WHILE_IDLE = "spring.datasource.testWhileIdle";
+
+ public static final String SPRING_DATASOURCE_TEST_ON_BORROW = "spring.datasource.testOnBorrow";
+
+ public static final String SPRING_DATASOURCE_TEST_ON_RETURN = "spring.datasource.testOnReturn";
+
+ public static final String SPRING_DATASOURCE_POOL_PREPARED_STATEMENTS = "spring.datasource.poolPreparedStatements";
+
+ public static final String SPRING_DATASOURCE_DEFAULT_AUTO_COMMIT = "spring.datasource.defaultAutoCommit";
+
+ public static final String SPRING_DATASOURCE_KEEP_ALIVE = "spring.datasource.keepAlive";
+
+ public static final String SPRING_DATASOURCE_MAX_POOL_PREPARED_STATEMENT_PER_CONNECTION_SIZE = "spring.datasource.maxPoolPreparedStatementPerConnectionSize";
+
+ public static final String DEVELOPMENT = "development";
+
+ public static final String CLASSPATH_MAIL_TEMPLATES_ALERT_MAIL_TEMPLATE_FTL = "classpath:mail_templates/alert_mail_template.ftl";
+
+ public static final String TR = "";
+
+ public static final String TD = "";
+
+ public static final String TD_END = " ";
+
+ public static final String TR_END = " ";
+
+ public static final String TITLE = "title";
+
+ public static final String CONTENT = "content";
+
+ public static final String TH = "";
+
+ public static final String TH_END = " ";
+
+ public static final int ALERT_SCAN_INTERVEL = 5000;
+
+ public static final String MARKDOWN_QUOTE = ">";
+
+ public static final String MARKDOWN_ENTER = "\n";
+
+ public static final String ENTERPRISE_WECHAT_CORP_ID = "enterprise.wechat.corp.id";
+
+ public static final String ENTERPRISE_WECHAT_SECRET = "enterprise.wechat.secret";
+
+ public static final String ENTERPRISE_WECHAT_TOKEN_URL = "enterprise.wechat.token.url";
+
+ public static final String ENTERPRISE_WECHAT_PUSH_URL = "enterprise.wechat.push.url";
+
+ public static final String ENTERPRISE_WECHAT_TEAM_SEND_MSG = "enterprise.wechat.team.send.msg";
+
+ public static final String ENTERPRISE_WECHAT_USER_SEND_MSG = "enterprise.wechat.user.send.msg";
+
+ public static final String ENTERPRISE_WECHAT_AGENT_ID = "enterprise.wechat.agent.id";
+
+ public static final String ENTERPRISE_WECHAT_USERS = "enterprise.wechat.users";
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java
new file mode 100644
index 0000000000..291ac5a82d
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+import org.apache.dolphinscheduler.common.enums.ShowType;
+import org.apache.dolphinscheduler.dao.entity.Alert;
+import com.alibaba.fastjson.JSON;
+
+import com.google.common.reflect.TypeToken;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Enterprise WeChat utils
+ */
+public class EnterpriseWeChatUtils {
+
+ public static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatUtils.class);
+
+ private static final String enterpriseWeChatCorpId = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_CORP_ID);
+
+ private static final String enterpriseWeChatSecret = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_SECRET);
+
+ private static final String enterpriseWeChatTokenUrl = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_TOKEN_URL);
+ private static String enterpriseWeChatTokenUrlReplace = enterpriseWeChatTokenUrl
+ .replaceAll("\\$corpId", enterpriseWeChatCorpId)
+ .replaceAll("\\$secret", enterpriseWeChatSecret);
+
+ private static final String enterpriseWeChatPushUrl = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_PUSH_URL);
+
+ private static final String enterpriseWeChatTeamSendMsg = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_TEAM_SEND_MSG);
+
+ private static final String enterpriseWeChatUserSendMsg = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USER_SEND_MSG);
+
+ public static final String enterpriseWeChatAgentId = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_AGENT_ID);
+
+ public static final String enterpriseWeChatUsers = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USERS);
+
+ /**
+ * get Enterprise WeChat token info
+ * @return token string info
+ * @throws IOException
+ */
+ public static String getToken() throws IOException {
+ String resp;
+
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpGet httpGet = new HttpGet(enterpriseWeChatTokenUrlReplace);
+ CloseableHttpResponse response = httpClient.execute(httpGet);
+ try {
+ HttpEntity entity = response.getEntity();
+ resp = EntityUtils.toString(entity, Constants.UTF_8);
+ EntityUtils.consume(entity);
+ } finally {
+ response.close();
+ }
+
+ Map map = JSON.parseObject(resp,
+ new TypeToken>() {
+ }.getType());
+ return map.get("access_token").toString();
+ }
+
+ /**
+ * make team single Enterprise WeChat message
+ * @param toParty
+ * @param agentId
+ * @param msg
+ * @return Enterprise WeChat send message
+ */
+ public static String makeTeamSendMsg(String toParty, String agentId, String msg) {
+ return enterpriseWeChatTeamSendMsg.replaceAll("\\$toParty", toParty)
+ .replaceAll("\\$agentId", agentId)
+ .replaceAll("\\$msg", msg);
+ }
+
+ /**
+ * make team multi Enterprise WeChat message
+ * @param toParty
+ * @param agentId
+ * @param msg
+ * @return Enterprise WeChat send message
+ */
+ public static String makeTeamSendMsg(Collection toParty, String agentId, String msg) {
+ String listParty = FuncUtils.mkString(toParty, "|");
+ return enterpriseWeChatTeamSendMsg.replaceAll("\\$toParty", listParty)
+ .replaceAll("\\$agentId", agentId)
+ .replaceAll("\\$msg", msg);
+ }
+
+ /**
+ * make team single user message
+ * @param toUser
+ * @param agentId
+ * @param msg
+ * @return Enterprise WeChat send message
+ */
+ public static String makeUserSendMsg(String toUser, String agentId, String msg) {
+ return enterpriseWeChatUserSendMsg.replaceAll("\\$toUser", toUser)
+ .replaceAll("\\$agentId", agentId)
+ .replaceAll("\\$msg", msg);
+ }
+
+ /**
+ * make team multi user message
+ * @param toUser
+ * @param agentId
+ * @param msg
+ * @return Enterprise WeChat send message
+ */
+ public static String makeUserSendMsg(Collection toUser, String agentId, String msg) {
+ String listUser = FuncUtils.mkString(toUser, "|");
+ return enterpriseWeChatUserSendMsg.replaceAll("\\$toUser", listUser)
+ .replaceAll("\\$agentId", agentId)
+ .replaceAll("\\$msg", msg);
+ }
+
+ /**
+ * send Enterprise WeChat
+ * @param charset
+ * @param data
+ * @param token
+ * @return Enterprise WeChat resp, demo: {"errcode":0,"errmsg":"ok","invaliduser":""}
+ * @throws IOException
+ */
+ public static String sendEnterpriseWeChat(String charset, String data, String token) throws IOException {
+ String enterpriseWeChatPushUrlReplace = enterpriseWeChatPushUrl.replaceAll("\\$token", token);
+
+ CloseableHttpClient httpclient = HttpClients.createDefault();
+ HttpPost httpPost = new HttpPost(enterpriseWeChatPushUrlReplace);
+ httpPost.setEntity(new StringEntity(data, charset));
+ CloseableHttpResponse response = httpclient.execute(httpPost);
+ String resp;
+ try {
+ HttpEntity entity = response.getEntity();
+ resp = EntityUtils.toString(entity, charset);
+ EntityUtils.consume(entity);
+ } finally {
+ response.close();
+ }
+ logger.info("Enterprise WeChat send [{}], param:{}, resp:{}", enterpriseWeChatPushUrl, data, resp);
+ return resp;
+ }
+
+ /**
+ * convert table to markdown style
+ * @param title
+ * @param content
+ * @return
+ */
+ public static String markdownTable(String title,String content){
+ List mapItemsList = JSONUtils.toList(content, LinkedHashMap.class);
+ StringBuilder contents = new StringBuilder(200);
+ for (LinkedHashMap mapItems : mapItemsList){
+
+ Set> entries = mapItems.entrySet();
+
+ Iterator> iterator = entries.iterator();
+
+ StringBuilder t = new StringBuilder(String.format("`%s`%s",title,Constants.MARKDOWN_ENTER));
+ while (iterator.hasNext()){
+
+ Map.Entry entry = iterator.next();
+ t.append(Constants.MARKDOWN_QUOTE);
+ t.append(entry.getKey()).append(":").append(entry.getValue());
+ t.append(Constants.MARKDOWN_ENTER);
+ }
+
+ contents.append(t);
+ }
+ return contents.toString();
+ }
+
+ /**
+ * convert text to markdown style
+ * @param title
+ * @param content
+ * @return
+ */
+ public static String markdownText(String title,String content){
+ if (StringUtils.isNotEmpty(content)){
+ List list;
+ try {
+ list = JSONUtils.toList(content,String.class);
+ }catch (Exception e){
+ logger.error("json format exception",e);
+ return null;
+ }
+
+ StringBuilder contents = new StringBuilder(100);
+ contents.append(String.format("`%s`\n",title));
+ for (String str : list){
+ contents.append(Constants.MARKDOWN_QUOTE);
+ contents.append(str);
+ contents.append(Constants.MARKDOWN_ENTER);
+ }
+
+ return contents.toString();
+
+ }
+ return null;
+ }
+
+ /**
+ * Determine the mardown style based on the show type of the alert
+ * @param alert
+ * @return
+ */
+ public static String markdownByAlert(Alert alert){
+ String result = "";
+ if (alert.getShowType() == ShowType.TABLE) {
+ result = markdownTable(alert.getTitle(),alert.getContent());
+ }else if(alert.getShowType() == ShowType.TEXT){
+ result = markdownText(alert.getTitle(),alert.getContent());
+ }
+ return result;
+
+ }
+
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/ExcelUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/ExcelUtils.java
new file mode 100644
index 0000000000..e033c775be
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/ExcelUtils.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * excel utils
+ */
+public class ExcelUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
+ /**
+ * generate excel file
+ * @param content
+ * @param title
+ * @param xlsFilePath
+ * @return
+ * @throws Exception
+ */
+ public static void genExcelFile(String content,String title,String xlsFilePath){
+ List itemsList;
+ try {
+ itemsList = JSONUtils.toList(content, LinkedHashMap.class);
+ }catch (Exception e){
+ logger.error(String.format("json format incorrect : %s",content),e);
+ throw new RuntimeException("json format incorrect",e);
+ }
+
+ if (itemsList == null || itemsList.size() == 0){
+ logger.error("itemsList is null");
+ throw new RuntimeException("itemsList is null");
+ }
+
+ LinkedHashMap headerMap = itemsList.get(0);
+
+ List headerList = new ArrayList<>();
+
+ Iterator> iter = headerMap.entrySet().iterator();
+ while (iter.hasNext()){
+ Map.Entry en = iter.next();
+ headerList.add(en.getKey());
+ }
+
+ HSSFWorkbook wb = null;
+ FileOutputStream fos = null;
+ try {
+ // declare a workbook
+ wb = new HSSFWorkbook();
+ // generate a table
+ HSSFSheet sheet = wb.createSheet();
+ HSSFRow row = sheet.createRow(0);
+ //set the height of the first line
+ row.setHeight((short)500);
+
+
+ //setting excel headers
+ for (int i = 0; i < headerList.size(); i++) {
+ HSSFCell cell = row.createCell(i);
+ cell.setCellValue(headerList.get(i));
+ }
+
+ //setting excel body
+ int rowIndex = 1;
+ for (LinkedHashMap itemsMap : itemsList){
+ Object[] values = itemsMap.values().toArray();
+ row = sheet.createRow(rowIndex);
+ //setting excel body height
+ row.setHeight((short)500);
+ rowIndex++;
+ for (int j = 0 ; j < values.length ; j++){
+ HSSFCell cell1 = row.createCell(j);
+ cell1.setCellValue(String.valueOf(values[j]));
+ }
+ }
+
+ for (int i = 0; i < headerList.size(); i++) {
+ sheet.setColumnWidth(i, headerList.get(i).length() * 800);
+
+ }
+
+ //setting file output
+ fos = new FileOutputStream(xlsFilePath + Constants.SINGLE_SLASH + title + Constants.EXCEL_SUFFIX_XLS);
+
+ wb.write(fos);
+
+ }catch (Exception e){
+ logger.error("generate excel error",e);
+ throw new RuntimeException("generate excel error",e);
+ }finally {
+ if (wb != null){
+ try {
+ wb.close();
+ } catch (IOException e) {
+ logger.error(e.getMessage(),e);
+ }
+ }
+ if (fos != null){
+ try {
+ fos.close();
+ } catch (IOException e) {
+ logger.error(e.getMessage(),e);
+ }
+ }
+ }
+ }
+
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/FuncUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/FuncUtils.java
new file mode 100644
index 0000000000..e682fde2e7
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/FuncUtils.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+public class FuncUtils {
+
+ static public String mkString(Iterable list, String split) {
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (String item : list) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(split);
+ }
+ sb.append(item);
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/JSONUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/JSONUtils.java
new file mode 100644
index 0000000000..cab85c49e6
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/JSONUtils.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+/**
+ * json utils
+ */
+public class JSONUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(JSONUtils.class);
+
+ /**
+ * object to json string
+ * @param object
+ * @return json string
+ */
+ public static String toJsonString(Object object) {
+ try{
+ return JSONObject.toJSONString(object,false);
+ } catch (Exception e) {
+ throw new RuntimeException("Json deserialization exception.", e);
+ }
+ }
+
+ /**
+ * json to list
+ *
+ * @param json
+ * @param clazz c
+ * @param
+ * @return
+ */
+ public static List toList(String json, Class clazz) {
+ if (StringUtils.isEmpty(json)) {
+ return null;
+ }
+ try {
+ return JSONArray.parseArray(json, clazz);
+ } catch (Exception e) {
+ logger.error("JSONArray.parseArray exception!",e);
+ }
+
+ return null;
+ }
+
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java
new file mode 100644
index 0000000000..607259c22b
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java
@@ -0,0 +1,456 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+import org.apache.dolphinscheduler.common.enums.ShowType;
+import freemarker.cache.StringTemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.mail.EmailException;
+import org.apache.commons.mail.HtmlEmail;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.ResourceUtils;
+
+import javax.mail.*;
+import javax.mail.internet.*;
+import java.io.*;
+import java.util.*;
+
+import static org.apache.dolphinscheduler.alert.utils.PropertyUtils.getInt;
+
+
+/**
+ * mail utils
+ */
+public class MailUtils {
+
+ public static final Logger logger = LoggerFactory.getLogger(MailUtils.class);
+
+ public static final String mailProtocol = PropertyUtils.getString(Constants.MAIL_PROTOCOL);
+
+ public static final String mailServerHost = PropertyUtils.getString(Constants.MAIL_SERVER_HOST);
+
+ public static final Integer mailServerPort = PropertyUtils.getInt(Constants.MAIL_SERVER_PORT);
+
+ public static final String mailSender = PropertyUtils.getString(Constants.MAIL_SENDER);
+
+ public static final String mailUser = PropertyUtils.getString(Constants.MAIL_USER);
+
+ public static final String mailPasswd = PropertyUtils.getString(Constants.MAIL_PASSWD);
+
+ public static final Boolean mailUseStartTLS = PropertyUtils.getBoolean(Constants.MAIL_SMTP_STARTTLS_ENABLE);
+
+ public static final Boolean mailUseSSL = PropertyUtils.getBoolean(Constants.MAIL_SMTP_SSL_ENABLE);
+
+ public static final String xlsFilePath = PropertyUtils.getString(Constants.XLS_FILE_PATH);
+
+ public static final String starttlsEnable = PropertyUtils.getString(Constants.MAIL_SMTP_STARTTLS_ENABLE);
+
+ public static final String sslEnable = PropertyUtils.getString(Constants.MAIL_SMTP_SSL_ENABLE);
+
+ public static final String sslTrust = PropertyUtils.getString(Constants.MAIL_SMTP_SSL_TRUST);
+
+ private static Template MAIL_TEMPLATE;
+
+ static {
+ Configuration cfg = new Configuration(Configuration.VERSION_2_3_21);
+ cfg.setDefaultEncoding(Constants.UTF_8);
+ StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
+ cfg.setTemplateLoader(stringTemplateLoader);
+ InputStreamReader isr = null;
+ try {
+ isr = new InputStreamReader(new FileInputStream(ResourceUtils.getFile(Constants.CLASSPATH_MAIL_TEMPLATES_ALERT_MAIL_TEMPLATE_FTL)),
+ Constants.UTF_8);
+
+ MAIL_TEMPLATE = new Template("alert_mail_template", isr, cfg);
+ } catch (Exception e) {
+ MAIL_TEMPLATE = null;
+ } finally {
+ IOUtils.closeQuietly(isr);
+ }
+ }
+
+
+ /**
+ * send mail to receivers
+ *
+ * @param receivers
+ * @param title
+ * @param content
+ * @return
+ */
+ public static Map sendMails(Collection receivers, String title, String content,ShowType showType) {
+ return sendMails(receivers, null, title, content, showType);
+ }
+
+ /**
+ * send mail
+ * @param receivers
+ * @param receiversCc cc
+ * @param title title
+ * @param content content
+ * @param showType mail type
+ * @return
+ */
+ public static Map sendMails(Collection receivers, Collection receiversCc, String title, String content, ShowType showType) {
+ Map retMap = new HashMap<>();
+ retMap.put(Constants.STATUS, false);
+
+ // if there is no receivers && no receiversCc, no need to process
+ if (CollectionUtils.isEmpty(receivers) && CollectionUtils.isEmpty(receiversCc)) {
+ return retMap;
+ }
+
+ receivers.removeIf((from) -> (StringUtils.isEmpty(from)));
+
+ if (showType == ShowType.TABLE || showType == ShowType.TEXT){
+ // send email
+ HtmlEmail email = new HtmlEmail();
+
+ try {
+ Session session = getSession();
+ email.setMailSession(session);
+ email.setFrom(mailSender);
+ email.setCharset(Constants.UTF_8);
+ if (CollectionUtils.isNotEmpty(receivers)){
+ // receivers mail
+ for (String receiver : receivers) {
+ email.addTo(receiver);
+ }
+ }
+
+ if (CollectionUtils.isNotEmpty(receiversCc)){
+ //cc
+ for (String receiverCc : receiversCc) {
+ email.addCc(receiverCc);
+ }
+ }
+ // sender mail
+ return getStringObjectMap(title, content, showType, retMap, email);
+ } catch (Exception e) {
+ handleException(receivers, retMap, e);
+ }
+ }else if (showType == ShowType.ATTACHMENT || showType == ShowType.TABLEATTACHMENT){
+ try {
+
+ String partContent = (showType == ShowType.ATTACHMENT ? "Please see the attachment " + title + Constants.EXCEL_SUFFIX_XLS : htmlTable(content,false));
+
+ attachment(receivers,receiversCc,title,content,partContent);
+
+ retMap.put(Constants.STATUS, true);
+ return retMap;
+ }catch (Exception e){
+ handleException(receivers, retMap, e);
+ return retMap;
+ }
+ }
+ return retMap;
+
+ }
+
+ /**
+ * html table content
+ * @param content
+ * @param showAll
+ * @return
+ */
+ private static String htmlTable(String content, boolean showAll){
+ if (StringUtils.isNotEmpty(content)){
+ List mapItemsList = JSONUtils.toList(content, LinkedHashMap.class);
+
+ if(!showAll && mapItemsList.size() > Constants.NUMBER_1000){
+ mapItemsList = mapItemsList.subList(0,Constants.NUMBER_1000);
+ }
+
+ StringBuilder contents = new StringBuilder(200);
+
+ boolean flag = true;
+
+ String title = "";
+ for (LinkedHashMap mapItems : mapItemsList){
+
+ Set> entries = mapItems.entrySet();
+
+ Iterator> iterator = entries.iterator();
+
+ StringBuilder t = new StringBuilder(Constants.TR);
+ StringBuilder cs = new StringBuilder(Constants.TR);
+ while (iterator.hasNext()){
+
+ Map.Entry entry = iterator.next();
+ t.append(Constants.TH).append(entry.getKey()).append(Constants.TH_END);
+ cs.append(Constants.TD).append(String.valueOf(entry.getValue())).append(Constants.TD_END);
+
+ }
+ t.append(Constants.TR_END);
+ cs.append(Constants.TR_END);
+ if (flag){
+ title = t.toString();
+ }
+ flag = false;
+ contents.append(cs);
+ }
+
+ return getTemplateContent(title,contents.toString());
+ }
+
+ return null;
+ }
+
+ /**
+ * html table content
+ * @param content
+ * @return
+ */
+ private static String htmlTable(String content){
+ return htmlTable(content,true);
+ }
+
+ /**
+ * html text content
+ * @param content
+ * @return
+ */
+ private static String htmlText(String content){
+
+ if (StringUtils.isNotEmpty(content)){
+ List list;
+ try {
+ list = JSONUtils.toList(content,String.class);
+ }catch (Exception e){
+ logger.error("json format exception",e);
+ return null;
+ }
+
+ StringBuilder contents = new StringBuilder(100);
+ for (String str : list){
+ contents.append(Constants.TR);
+ contents.append(Constants.TD).append(str).append(Constants.TD_END);
+ contents.append(Constants.TR_END);
+ }
+
+ return getTemplateContent(null,contents.toString());
+
+ }
+
+ return null;
+ }
+
+
+
+
+ /**
+ * send mail as Excel attachment
+ *
+ * @param receivers
+ * @param title
+ * @throws Exception
+ */
+ private static void attachment(Collection receivers,Collection receiversCc,String title,String content,String partContent)throws Exception{
+ MimeMessage msg = getMimeMessage(receivers);
+
+ attachContent(receiversCc, title, content,partContent, msg);
+ }
+
+ /**
+ * get MimeMessage
+ * @param receivers
+ * @return
+ * @throws MessagingException
+ */
+ private static MimeMessage getMimeMessage(Collection receivers) throws MessagingException {
+// Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
+// final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
+
+ // 1. The first step in creating mail: creating session
+ Session session = getSession();
+ // Setting debug mode, can be turned off
+ session.setDebug(false);
+
+ // 2. creating mail: Creating a MimeMessage
+ MimeMessage msg = new MimeMessage(session);
+ // 3. set sender
+ msg.setFrom(new InternetAddress(mailSender));
+ // 4. set receivers
+ for (String receiver : receivers) {
+ msg.addRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse(receiver));
+ }
+ return msg;
+ }
+
+ /**
+ * get session
+ * @return
+ */
+ private static Session getSession() {
+ Properties props = new Properties();
+ props.setProperty(Constants.MAIL_HOST, mailServerHost);
+ props.setProperty(Constants.MAIL_PORT, String.valueOf(mailServerPort));
+ props.setProperty(Constants.MAIL_SMTP_AUTH, Constants.STRING_TRUE);
+ props.setProperty(Constants.MAIL_TRANSPORT_PROTOCOL, mailProtocol);
+ props.setProperty(Constants.MAIL_SMTP_STARTTLS_ENABLE, starttlsEnable);
+ props.setProperty(Constants.MAIL_SMTP_SSL_ENABLE, sslEnable);
+ props.setProperty(Constants.MAIL_SMTP_SSL_TRUST, sslTrust);
+
+ Authenticator auth = new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ // mail username and password
+ return new PasswordAuthentication(mailUser, mailPasswd);
+ }
+ };
+
+ Session session = Session.getInstance(props, auth);
+ return session;
+ }
+
+ /**
+ *
+ * @param receiversCc
+ * @param title
+ * @param content
+ * @param partContent
+ * @param msg
+ * @throws MessagingException
+ * @throws IOException
+ */
+ private static void attachContent(Collection receiversCc, String title, String content, String partContent,MimeMessage msg) throws MessagingException, IOException {
+ /**
+ * set receiverCc
+ */
+ if(CollectionUtils.isNotEmpty(receiversCc)){
+ for (String receiverCc : receiversCc){
+ msg.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(receiverCc));
+ }
+ }
+
+ // set receivers type to cc
+ // msg.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(propMap.get("${CC}")));
+ // set subject
+ msg.setSubject(title);
+ MimeMultipart partList = new MimeMultipart();
+ // set signature
+ MimeBodyPart part1 = new MimeBodyPart();
+ part1.setContent(partContent, Constants.TEXT_HTML_CHARSET_UTF_8);
+ // set attach file
+ MimeBodyPart part2 = new MimeBodyPart();
+ // make excel file
+ ExcelUtils.genExcelFile(content,title,xlsFilePath);
+ File file = new File(xlsFilePath + Constants.SINGLE_SLASH + title + Constants.EXCEL_SUFFIX_XLS);
+ part2.attachFile(file);
+ part2.setFileName(MimeUtility.encodeText(title + Constants.EXCEL_SUFFIX_XLS));
+ // add components to collection
+ partList.addBodyPart(part1);
+ partList.addBodyPart(part2);
+ msg.setContent(partList);
+ // 5. send Transport
+ Transport.send(msg);
+ // 6. delete saved file
+ deleteFile(file);
+ }
+
+ /**
+ *
+ * @param title
+ * @param content
+ * @param showType
+ * @param retMap
+ * @param email
+ * @return
+ * @throws EmailException
+ */
+ private static Map getStringObjectMap(String title, String content, ShowType showType, Map retMap, HtmlEmail email) throws EmailException {
+
+ /**
+ * the subject of the message to be sent
+ */
+ email.setSubject(title);
+ /**
+ * to send information, you can use HTML tags in mail content because of the use of HtmlEmail
+ */
+ if (showType == ShowType.TABLE) {
+ email.setMsg(htmlTable(content));
+ } else if (showType == ShowType.TEXT) {
+ email.setMsg(htmlText(content));
+ }
+
+ // send
+ email.send();
+
+ retMap.put(Constants.STATUS, true);
+
+ return retMap;
+ }
+
+ /**
+ * file delete
+ * @param file
+ */
+ public static void deleteFile(File file){
+ if(file.exists()){
+ if(file.delete()){
+ logger.info("delete success:"+file.getAbsolutePath()+file.getName());
+ }else{
+ logger.info("delete fail"+file.getAbsolutePath()+file.getName());
+ }
+ }else{
+ logger.info("file not exists:"+file.getAbsolutePath()+file.getName());
+ }
+ }
+
+
+ /**
+ *
+ * @param receivers
+ * @param retMap
+ * @param e
+ */
+ private static void handleException(Collection receivers, Map retMap, Exception e) {
+ logger.error("Send email to {} failed", StringUtils.join(",", receivers), e);
+ retMap.put(Constants.MESSAGE, "Send email to {" + StringUtils.join(",", receivers) + "} failed," + e.toString());
+ }
+
+ /**
+ *
+ * @param title
+ * @param content
+ * @return
+ */
+ private static String getTemplateContent(String title,String content){
+ StringWriter out = new StringWriter();
+ Map map = new HashMap<>();
+ if(null != title){
+ map.put(Constants.TITLE,title);
+ }
+ map.put(Constants.CONTENT,content);
+ try {
+ MAIL_TEMPLATE.process(map, out);
+ return out.toString();
+ } catch (TemplateException e) {
+ logger.error(e.getMessage(),e);
+ } catch (IOException e) {
+ logger.error(e.getMessage(),e);
+ }
+
+ return null;
+ }
+}
diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/PropertyUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/PropertyUtils.java
new file mode 100644
index 0000000000..225e4df3c1
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/PropertyUtils.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import static org.apache.dolphinscheduler.alert.utils.Constants.ALERT_PROPERTIES_PATH;
+import static org.apache.dolphinscheduler.alert.utils.Constants.DATA_SOURCE_PROPERTIES_PATH;
+
+/**
+ * property utils
+ * single instance
+ */
+public class PropertyUtils {
+
+ /**
+ * logger
+ */
+ private static final Logger logger = LoggerFactory.getLogger(PropertyUtils.class);
+
+ private static final Properties properties = new Properties();
+
+ private static final PropertyUtils propertyUtils = new PropertyUtils();
+
+ private PropertyUtils(){
+ init();
+ }
+
+ private void init(){
+ String[] propertyFiles = new String[]{ALERT_PROPERTIES_PATH,DATA_SOURCE_PROPERTIES_PATH};
+ for (String fileName : propertyFiles) {
+ InputStream fis = null;
+ try {
+ fis = PropertyUtils.class.getResourceAsStream(fileName);
+ properties.load(fis);
+
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ System.exit(1);
+ } finally {
+ IOUtils.closeQuietly(fis);
+ }
+ }
+ }
+
+/*
+ public static PropertyUtils getInstance(){
+ return propertyUtils;
+ }
+*/
+
+ /**
+ * get property value
+ *
+ * @param key property name
+ * @return
+ */
+ public static String getString(String key) {
+ return properties.getProperty(key);
+ }
+
+ /**
+ * get property value
+ *
+ * @param key property name
+ * @return get property int value , if key == null, then return -1
+ */
+ public static int getInt(String key) {
+ return getInt(key, -1);
+ }
+
+ /**
+ *
+ * @param key
+ * @param defaultValue
+ * @return
+ */
+ public static int getInt(String key, int defaultValue) {
+ String value = getString(key);
+ if (value == null) {
+ return defaultValue;
+ }
+
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ logger.info(e.getMessage(),e);
+ }
+ return defaultValue;
+ }
+
+ /**
+ * get property value
+ *
+ * @param key property name
+ * @return
+ */
+ public static Boolean getBoolean(String key) {
+ String value = properties.getProperty(key.trim());
+ if(null != value){
+ return Boolean.parseBoolean(value);
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @param key
+ * @return
+ */
+ public static long getLong(String key) {
+ return getLong(key,-1);
+ }
+
+ /**
+ *
+ * @param key
+ * @param defaultVal
+ * @return
+ */
+ public static long getLong(String key, long defaultVal) {
+ String val = getString(key);
+ return val == null ? defaultVal : Long.parseLong(val);
+ }
+
+
+ /**
+ *
+ * @param key
+ * @param defaultVal
+ * @return
+ */
+ public double getDouble(String key, double defaultVal) {
+ String val = getString(key);
+ return val == null ? defaultVal : Double.parseDouble(val);
+ }
+
+
+ /**
+ * get array
+ * @param key property name
+ * @param splitStr separator
+ * @return
+ */
+ public static String[] getArray(String key, String splitStr) {
+ String value = getString(key);
+ if (value == null) {
+ return null;
+ }
+ try {
+ String[] propertyArray = value.split(splitStr);
+ return propertyArray;
+ } catch (NumberFormatException e) {
+ logger.info(e.getMessage(),e);
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param key
+ * @param type
+ * @param defaultValue
+ * @param
+ * @return get enum value
+ */
+ public > T getEnum(String key, Class type,
+ T defaultValue) {
+ String val = getString(key);
+ return val == null ? defaultValue : Enum.valueOf(type, val);
+ }
+}
diff --git a/escheduler-alert/src/main/resources/alert.properties b/dolphinscheduler-alert/src/main/resources/alert.properties
similarity index 100%
rename from escheduler-alert/src/main/resources/alert.properties
rename to dolphinscheduler-alert/src/main/resources/alert.properties
diff --git a/dolphinscheduler-alert/src/main/resources/alert_logback.xml b/dolphinscheduler-alert/src/main/resources/alert_logback.xml
new file mode 100644
index 0000000000..2b617817e0
--- /dev/null
+++ b/dolphinscheduler-alert/src/main/resources/alert_logback.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+ [%level] %date{yyyy-MM-dd HH:mm:ss.SSS} %logger{96}:[%line] - %msg%n
+
+ UTF-8
+
+
+
+
+ ${log.base}/dolphinscheduler-alert.log
+
+ ${log.base}/dolphinscheduler-alert.%d{yyyy-MM-dd_HH}.%i.log
+ 20
+ 64MB
+
+
+
+ [%level] %date{yyyy-MM-dd HH:mm:ss.SSS} %logger{96}:[%line] - %msg%n
+
+ UTF-8
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/escheduler-alert/src/main/resources/application_alert.properties b/dolphinscheduler-alert/src/main/resources/application_alert.properties
similarity index 100%
rename from escheduler-alert/src/main/resources/application_alert.properties
rename to dolphinscheduler-alert/src/main/resources/application_alert.properties
diff --git a/escheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl b/dolphinscheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl
similarity index 100%
rename from escheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl
rename to dolphinscheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl
diff --git a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java
new file mode 100644
index 0000000000..527d828e40
--- /dev/null
+++ b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+import com.alibaba.fastjson.JSON;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Please manually modify the configuration file before testing.
+ * file: alert.properties
+ * enterprise.wechat.corp.id
+ * enterprise.wechat.secret
+ * enterprise.wechat.token.url
+ * enterprise.wechat.push.url
+ * enterprise.wechat.send.msg
+ * enterprise.wechat.agent.id
+ * enterprise.wechat.users
+ */
+@Ignore
+public class EnterpriseWeChatUtilsTest {
+
+ private String agentId = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_AGENT_ID); // app id
+ private Collection listUserId = Arrays.asList(PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USERS).split(","));
+
+ // Please change
+ private String partyId = "2";
+ private Collection listPartyId = Arrays.asList("2","4");
+ @Test
+ public void testSendSingleTeamWeChat() {
+ try {
+ String token = EnterpriseWeChatUtils.getToken();
+ String msg = EnterpriseWeChatUtils.makeTeamSendMsg(partyId, agentId, "hello world");
+ String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token);
+
+ String errmsg = JSON.parseObject(resp).getString("errmsg");
+ Assert.assertEquals(errmsg, "ok");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testSendMultiTeamWeChat() {
+
+ try {
+ String token = EnterpriseWeChatUtils.getToken();
+ String msg = EnterpriseWeChatUtils.makeTeamSendMsg(listPartyId, agentId, "hello world");
+ String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token);
+
+ String errmsg = JSON.parseObject(resp).getString("errmsg");
+ Assert.assertEquals(errmsg, "ok");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testSendSingleUserWeChat() {
+ try {
+ String token = EnterpriseWeChatUtils.getToken();
+ String msg = EnterpriseWeChatUtils.makeUserSendMsg(listUserId.stream().findFirst().get(), agentId, "您的会议室已经预定,稍后会同步到`邮箱` \n" +
+ ">**事项详情** \n" +
+ ">事 项:开会 " +
+ ">组织者:@miglioguan \n" +
+ ">参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang \n" +
+ "> \n" +
+ ">会议室:广州TIT 1楼 301 \n" +
+ ">日 期:2018年5月18日 \n" +
+ ">时 间:上午9:00-11:00 \n" +
+ "> \n" +
+ ">请准时参加会议。 \n" +
+ "> \n" +
+ ">如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)\"");
+
+ String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token);
+
+ String errmsg = JSON.parseObject(resp).getString("errmsg");
+ Assert.assertEquals(errmsg, "ok");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testSendMultiUserWeChat() {
+ try {
+ String token = EnterpriseWeChatUtils.getToken();
+
+ String msg = EnterpriseWeChatUtils.makeUserSendMsg(listUserId, agentId, "hello world");
+ String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token);
+
+ String errmsg = JSON.parseObject(resp).getString("errmsg");
+ Assert.assertEquals(errmsg, "ok");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java
new file mode 100644
index 0000000000..7525256f9b
--- /dev/null
+++ b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.alert.utils;
+
+
+import org.apache.dolphinscheduler.common.enums.AlertType;
+import org.apache.dolphinscheduler.common.enums.ShowType;
+import org.apache.dolphinscheduler.dao.AlertDao;
+import org.apache.dolphinscheduler.dao.DaoFactory;
+import org.apache.dolphinscheduler.dao.entity.Alert;
+import org.apache.dolphinscheduler.dao.entity.User;
+import freemarker.cache.StringTemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import org.apache.commons.io.IOUtils;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.ResourceUtils;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.util.*;
+
+
+/**
+ */
+@Ignore
+public class MailUtilsTest {
+ private static final Logger logger = LoggerFactory.getLogger(MailUtilsTest.class);
+ @Test
+ public void testSendMails() {
+ String[] receivers = new String[]{"xx@xx.com"};
+ String[] receiversCc = new String[]{"xxx@xxx.com"};
+
+ String content ="[\"id:69\"," +
+ "\"name:UserBehavior-0--1193959466\"," +
+ "\"Job name: 启动工作流\"," +
+ "\"State: SUCCESS\"," +
+ "\"Recovery:NO\"," +
+ "\"Run time: 1\"," +
+ "\"Start time: 2018-08-06 10:31:34.0\"," +
+ "\"End time: 2018-08-06 10:31:49.0\"," +
+ "\"Host: 192.168.xx.xx\"," +
+ "\"Notify group :4\"]";
+
+ Alert alert = new Alert();
+ alert.setTitle("Mysql异常");
+ alert.setShowType(ShowType.TEXT);
+ alert.setContent(content);
+ alert.setAlertType(AlertType.EMAIL);
+ alert.setAlertGroupId(4);
+
+ MailUtils.sendMails(Arrays.asList(receivers),Arrays.asList(receiversCc),alert.getTitle(),alert.getContent(), ShowType.TEXT);
+ }
+
+
+ @Test
+ public void testQuery(){
+ AlertDao alertDao = DaoFactory.getDaoInstance(AlertDao.class);
+ List alerts = alertDao.listWaitExecutionAlert();
+
+ String[] mails = new String[]{"xx@xx.com"};
+
+ for(Alert alert : alerts){
+ MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), alert.getShowType());
+ }
+
+ }
+
+ public String list2String(){
+
+ LinkedHashMap map1 = new LinkedHashMap<>();
+ map1.put("mysql服务名称","mysql200");
+ map1.put("mysql地址","192.168.xx.xx");
+ map1.put("端口","3306");
+ map1.put("期间内没有使用索引的查询数握","80");
+ map1.put("数据库客户端连接数","190");
+
+ LinkedHashMap map2 = new LinkedHashMap<>();
+ map2.put("mysql服务名称","mysql210");
+ map2.put("mysql地址","192.168.xx.xx");
+ map2.put("端口","3306");
+ map2.put("期间内没有使用索引的查询数握","10");
+ map2.put("数据库客户端连接数","90");
+
+ List> maps = new ArrayList<>();
+ maps.add(0,map1);
+ maps.add(1,map2);
+ String mapjson = JSONUtils.toJsonString(maps);
+ logger.info(mapjson);
+
+ return mapjson;
+
+ }
+
+ @Test
+ public void testSendTableMail(){
+ String[] mails = new String[]{"xx@xx.com"};
+ Alert alert = new Alert();
+ alert.setTitle("Mysql Exception");
+ alert.setShowType(ShowType.TABLE);
+ String content= list2String();
+ alert.setContent(content);
+ alert.setAlertType(AlertType.EMAIL);
+ alert.setAlertGroupId(1);
+ MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE);
+ }
+
+ /**
+ * Used to test add alarm information, mail sent
+ * Text
+ */
+ @Test
+ public void addAlertText(){
+ AlertDao alertDao = DaoFactory.getDaoInstance(AlertDao.class);
+ Alert alert = new Alert();
+ alert.setTitle("Mysql Exception");
+ alert.setShowType(ShowType.TEXT);
+ alert.setContent("[\"告警时间:2018-02-05\", \"服务名:MYSQL_ALTER\", \"告警名:MYSQL_ALTER_DUMP\", \"获取告警异常!,接口报错,异常信息:timed out\", \"请求地址:http://blog.csdn.net/dreamInTheWorld/article/details/78539286\"]");
+ alert.setAlertType(AlertType.EMAIL);
+ alert.setAlertGroupId(1);
+ alertDao.addAlert(alert);
+ }
+
+
+ /**
+ * Used to test add alarm information, mail sent
+ * Table
+ */
+ @Test
+ public void addAlertTable(){
+ AlertDao alertDao = DaoFactory.getDaoInstance(AlertDao.class);
+ Alert alert = new Alert();
+ alert.setTitle("Mysql Exception");
+ alert.setShowType(ShowType.TABLE);
+
+ String content = list2String();
+ alert.setContent(content);
+ alert.setAlertType(AlertType.EMAIL);
+ alert.setAlertGroupId(1);
+ alertDao.addAlert(alert);
+ }
+
+ @Test
+ public void testAlertDao(){
+ AlertDao alertDao = DaoFactory.getDaoInstance(AlertDao.class);
+ List users = alertDao.listUserByAlertgroupId(3);
+ logger.info(users.toString());
+ }
+
+ @Test
+ public void testAttachmentFile()throws Exception{
+ String[] mails = new String[]{"xx@xx.com"};
+ Alert alert = new Alert();
+ alert.setTitle("Mysql Exception");
+ alert.setShowType(ShowType.ATTACHMENT);
+ String content = list2String();
+ alert.setContent(content);
+ alert.setAlertType(AlertType.EMAIL);
+ alert.setAlertGroupId(1);
+ MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.ATTACHMENT);
+ }
+
+ @Test
+ public void testTableAttachmentFile()throws Exception{
+ String[] mails = new String[]{"xx@xx.com"};
+ Alert alert = new Alert();
+ alert.setTitle("Mysql Exception");
+ alert.setShowType(ShowType.TABLEATTACHMENT);
+ String content = list2String();
+ alert.setContent(content);
+ alert.setAlertType(AlertType.EMAIL);
+ alert.setAlertGroupId(1);
+ MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.TABLEATTACHMENT);
+ }
+
+ @Test
+ public void template(){
+ Template MAIL_TEMPLATE;
+ Configuration cfg = new Configuration(Configuration.VERSION_2_3_21);
+ cfg.setDefaultEncoding(Constants.UTF_8);
+ StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
+ cfg.setTemplateLoader(stringTemplateLoader);
+ InputStreamReader isr = null;
+ try {
+ isr = new InputStreamReader(new FileInputStream(ResourceUtils.getFile(Constants.CLASSPATH_MAIL_TEMPLATES_ALERT_MAIL_TEMPLATE_FTL)),
+ Constants.UTF_8);
+
+ MAIL_TEMPLATE = new Template("alert_mail_template", isr, cfg);
+ } catch (Exception e) {
+ MAIL_TEMPLATE = null;
+ } finally {
+ IOUtils.closeQuietly(isr);
+ }
+
+
+ StringWriter out = new StringWriter();
+ Map map = new HashMap<>();
+ map.put(Constants.TITLE,"title_test");
+ try {
+ MAIL_TEMPLATE.process(map, out);
+ logger.info(out.toString());
+
+ } catch (TemplateException e) {
+ logger.error(e.getMessage(),e);
+ } catch (IOException e) {
+ logger.error(e.getMessage(),e);
+ }
+
+ }
+
+}
diff --git a/dolphinscheduler-api/pom.xml b/dolphinscheduler-api/pom.xml
new file mode 100644
index 0000000000..2dd599c579
--- /dev/null
+++ b/dolphinscheduler-api/pom.xml
@@ -0,0 +1,219 @@
+
+ 4.0.0
+
+ org.apache.dolphinscheduler
+ dolphinscheduler
+ 1.1.0-SNAPSHOT
+
+ dolphinscheduler-api
+ jar
+
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-alert
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-server
+
+
+ io.netty
+ netty
+
+
+ io.netty
+ netty-all
+
+
+ com.google
+ netty
+
+
+ leveldbjni-all
+ org.fusesource.leveldbjni
+
+
+ protobuf-java
+ com.google.protobuf
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+ log4j-to-slf4j
+ org.apache.logging.log4j
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jetty
+
+
+ org.eclipse.jetty.websocket
+ javax-websocket-server-impl
+
+
+ org.eclipse.jetty.websocket
+ websocket-server
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.ow2.asm
+ asm
+
+
+ org.springframework.boot
+ spring-boot
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+
+ org.springframework
+ spring-context
+
+
+
+ org.apache.httpcomponents
+ httpcore
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
+
+ com.alibaba
+ fastjson
+
+
+
+ commons-collections
+ commons-collections
+
+
+
+ org.quartz-scheduler
+ quartz
+
+
+ c3p0
+ c3p0
+
+
+
+
+
+ org.quartz-scheduler
+ quartz-jobs
+
+
+
+ io.springfox
+ springfox-swagger2
+ 2.9.2
+
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.9.2
+
+
+
+ com.github.xiaoymin
+ swagger-bootstrap-ui
+ 1.9.3
+
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-rpc
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+ maven-assembly-plugin
+ 2.6
+
+
+ src/main/assembly/package.xml
+
+ false
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+
+
\ No newline at end of file
diff --git a/dolphinscheduler-api/src/main/assembly/package.xml b/dolphinscheduler-api/src/main/assembly/package.xml
new file mode 100644
index 0000000000..1c24d64b03
--- /dev/null
+++ b/dolphinscheduler-api/src/main/assembly/package.xml
@@ -0,0 +1,74 @@
+
+ cluster
+
+ dir
+
+ false
+
+
+ src/main/resources
+
+ **/*.properties
+ **/*.xml
+ **/*.json
+
+ conf
+
+
+ ${project.parent.basedir}/dolphinscheduler-common/src/main/resources
+
+ **/*.properties
+ **/*.xml
+ **/*.json
+
+ conf
+
+
+ ${project.parent.basedir}/dolphinscheduler-common/src/main/resources/bin
+
+ *.*
+
+ 755
+ bin
+
+
+ ${project.parent.basedir}/dolphinscheduler-dao/src/main/resources
+
+ **/*.properties
+ **/*.xml
+ **/*.json
+
+ conf
+
+
+ ${project.parent.basedir}/dolphinscheduler-api/src/main/resources
+
+ **/*.properties
+ **/*.xml
+ **/*.json
+
+ conf
+
+
+ target/
+
+ dolphinscheduler-api-${project.version}.jar
+
+ lib
+
+
+
+
+ lib
+ true
+
+ javax.servlet:servlet-api
+ org.eclipse.jetty.aggregate:jetty-all
+ org.slf4j:slf4j-log4j12
+
+
+
+
\ No newline at end of file
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java
new file mode 100644
index 0000000000..d999f375a0
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@SpringBootApplication
+@ServletComponentScan
+@ComponentScan("cn.escheduler")
+@EnableSwagger2
+public class ApiApplicationServer extends SpringBootServletInitializer {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ApiApplicationServer.class, args);
+ }
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/CombinedApplicationServer.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/CombinedApplicationServer.java
new file mode 100644
index 0000000000..df8c855949
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/CombinedApplicationServer.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api;
+
+import org.apache.dolphinscheduler.alert.AlertServer;
+import org.apache.dolphinscheduler.dao.AlertDao;
+import org.apache.dolphinscheduler.dao.ProcessDao;
+import org.apache.dolphinscheduler.server.master.MasterServer;
+import org.apache.dolphinscheduler.server.rpc.LoggerServer;
+import org.apache.dolphinscheduler.server.worker.WorkerServer;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@SpringBootApplication
+@ServletComponentScan
+@ComponentScan("cn.escheduler")
+@EnableSwagger2
+public class CombinedApplicationServer extends SpringBootServletInitializer {
+
+ public static void main(String[] args) throws Exception {
+
+ ConfigurableApplicationContext context = SpringApplication.run(ApiApplicationServer.class, args);
+ ProcessDao processDao = context.getBean(ProcessDao.class);
+ AlertDao alertDao = context.getBean(AlertDao.class);
+
+ MasterServer master = new MasterServer(processDao);
+ master.run(processDao);
+
+ WorkerServer workerServer = new WorkerServer(processDao, alertDao);
+ workerServer.run(processDao, alertDao);
+
+ LoggerServer server = new LoggerServer();
+ server.start();
+
+ AlertServer alertServer = AlertServer.getInstance();
+ alertServer.start();
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java
new file mode 100644
index 0000000000..8ae2dbc529
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.configuration;
+
+import org.apache.dolphinscheduler.api.interceptor.LoginHandlerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.*;
+import org.springframework.web.servlet.i18n.CookieLocaleResolver;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+
+import java.util.Locale;
+
+
+/**
+ * application configuration
+ */
+@Configuration
+public class AppConfiguration implements WebMvcConfigurer {
+
+ public static final String LOGIN_INTERCEPTOR_PATH_PATTERN = "/**/*";
+ public static final String LOGIN_PATH_PATTERN = "/login";
+ public static final String PATH_PATTERN = "/**";
+ public static final String LOCALE_LANGUAGE_COOKIE = "language";
+ public static final int COOKIE_MAX_AGE = 3600;
+
+
+ @Bean
+ public LoginHandlerInterceptor loginInterceptor() {
+ return new LoginHandlerInterceptor();
+ }
+
+
+ /**
+ * Cookie
+ */
+ @Bean(name = "localeResolver")
+ public LocaleResolver localeResolver() {
+ CookieLocaleResolver localeResolver = new CookieLocaleResolver();
+ localeResolver.setCookieName(LOCALE_LANGUAGE_COOKIE);
+ /** set default locale **/
+ localeResolver.setDefaultLocale(Locale.US);
+ /** set cookie max age **/
+ localeResolver.setCookieMaxAge(COOKIE_MAX_AGE);
+ return localeResolver;
+ }
+
+ @Bean
+ public LocaleChangeInterceptor localeChangeInterceptor() {
+ LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
+ /** **/
+ lci.setParamName("language");
+
+ return lci;
+ }
+
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ //i18n
+ registry.addInterceptor(localeChangeInterceptor());
+
+ registry.addInterceptor(loginInterceptor()).addPathPatterns(LOGIN_INTERCEPTOR_PATH_PATTERN).excludePathPatterns(LOGIN_PATH_PATTERN,"/swagger-resources/**", "/webjars/**", "/v2/**", "/doc.html", "*.html", "/ui/**");
+ }
+
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
+ registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
+ registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+ registry.addResourceHandler("/ui/**").addResourceLocations("file:ui/");
+ }
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/ui/").setViewName("forward:/ui/index.html");
+ registry.addViewController("/").setViewName("forward:/ui/index.html");
+ }
+
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping(PATH_PATTERN).allowedOrigins("*").allowedMethods("*");
+ }
+
+
+ /**
+ * Turn off suffix-based content negotiation
+ *
+ * @param configurer
+ */
+ @Override
+ public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
+ configurer.favorPathExtension(false);
+ }
+
+
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/ServiceModelToSwagger2MapperImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/ServiceModelToSwagger2MapperImpl.java
new file mode 100644
index 0000000000..9821779ee4
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/ServiceModelToSwagger2MapperImpl.java
@@ -0,0 +1,509 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.configuration;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import io.swagger.models.*;
+import io.swagger.models.parameters.Parameter;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.MessageSource;
+import org.springframework.context.annotation.Primary;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.stereotype.Component;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiListing;
+import springfox.documentation.service.Documentation;
+import springfox.documentation.service.ResourceListing;
+import springfox.documentation.swagger2.mappers.*;
+
+import java.util.*;
+
+import static com.google.common.collect.Maps.newTreeMap;
+
+/**
+ * application configuration
+ */
+@Component(value = "ServiceModelToSwagger2Mapper")
+@Primary
+public class ServiceModelToSwagger2MapperImpl extends ServiceModelToSwagger2Mapper {
+
+
+ @Autowired
+ private ModelMapper modelMapper;
+ @Autowired
+ private ParameterMapper parameterMapper;
+ @Autowired
+ private SecurityMapper securityMapper;
+ @Autowired
+ private LicenseMapper licenseMapper;
+ @Autowired
+ private VendorExtensionsMapper vendorExtensionsMapper;
+
+ @Autowired
+ private MessageSource messageSource;
+
+ @Override
+ public Swagger mapDocumentation(Documentation from) {
+
+ if (from == null) {
+ return null;
+ }
+
+ Swagger swagger = new Swagger();
+
+ swagger.setVendorExtensions(vendorExtensionsMapper.mapExtensions(from.getVendorExtensions()));
+ swagger.setSchemes(mapSchemes(from.getSchemes()));
+ swagger.setPaths(mapApiListings(from.getApiListings()));
+ swagger.setHost(from.getHost());
+ swagger.setDefinitions(modelsFromApiListings( from.getApiListings() ) );
+ swagger.setSecurityDefinitions(securityMapper.toSecuritySchemeDefinitions(from.getResourceListing()));
+ ApiInfo info = fromResourceListingInfo(from);
+ if (info != null) {
+ swagger.setInfo(mapApiInfo(info));
+ }
+ swagger.setBasePath(from.getBasePath());
+ swagger.setTags(tagSetToTagList(from.getTags()));
+ List list2 = from.getConsumes();
+ if (list2 != null) {
+ swagger.setConsumes(new ArrayList(list2));
+ } else {
+ swagger.setConsumes(null);
+ }
+ List list3 = from.getProduces();
+ if (list3 != null) {
+ swagger.setProduces(new ArrayList(list3));
+ } else {
+ swagger.setProduces(null);
+ }
+
+ return swagger;
+ }
+
+
+ @Override
+ protected Info mapApiInfo(ApiInfo from) {
+
+ if (from == null) {
+ return null;
+ }
+
+ Info info = new Info();
+
+ info.setLicense(licenseMapper.apiInfoToLicense(from));
+ info.setVendorExtensions(vendorExtensionsMapper.mapExtensions(from.getVendorExtensions()));
+ info.setTermsOfService(from.getTermsOfServiceUrl());
+ info.setContact(map(from.getContact()));
+ info.setDescription(from.getDescription());
+ info.setVersion(from.getVersion());
+ info.setTitle(from.getTitle());
+
+ return info;
+ }
+
+ @Override
+ protected Contact map(springfox.documentation.service.Contact from) {
+
+ if (from == null) {
+ return null;
+ }
+
+ Contact contact = new Contact();
+
+ contact.setName(from.getName());
+ contact.setUrl(from.getUrl());
+ contact.setEmail(from.getEmail());
+
+ return contact;
+ }
+
+ @Override
+ protected io.swagger.models.Operation mapOperation(springfox.documentation.service.Operation from) {
+
+ if (from == null) {
+ return null;
+ }
+
+ Locale locale = LocaleContextHolder.getLocale();
+
+ io.swagger.models.Operation operation = new io.swagger.models.Operation();
+
+ operation.setSecurity(mapAuthorizations(from.getSecurityReferences()));
+ operation.setVendorExtensions(vendorExtensionsMapper.mapExtensions(from.getVendorExtensions()));
+ operation.setDescription(messageSource.getMessage(from.getNotes(), null, from.getNotes(), locale));
+ operation.setOperationId(from.getUniqueId());
+ operation.setResponses(mapResponseMessages(from.getResponseMessages()));
+ operation.setSchemes(stringSetToSchemeList(from.getProtocol()));
+ Set tagsSet = new HashSet<>(1);
+
+ if(from.getTags() != null && from.getTags().size() > 0){
+
+ List list = new ArrayList(tagsSet.size());
+
+ Iterator it = from.getTags().iterator();
+ while(it.hasNext())
+ {
+ String tag = it.next();
+ list.add(StringUtils.isNotBlank(tag) ? messageSource.getMessage(tag, null, tag, locale) : " ");
+ }
+
+ operation.setTags(list);
+ }else {
+ operation.setTags(null);
+ }
+
+ operation.setSummary(from.getSummary());
+ Set set1 = from.getConsumes();
+ if (set1 != null) {
+ operation.setConsumes(new ArrayList(set1));
+ } else {
+ operation.setConsumes(null);
+ }
+
+ Set set2 = from.getProduces();
+ if (set2 != null) {
+ operation.setProduces(new ArrayList(set2));
+ } else {
+ operation.setProduces(null);
+ }
+
+
+ operation.setParameters(parameterListToParameterList(from.getParameters()));
+ if (from.getDeprecated() != null) {
+ operation.setDeprecated(Boolean.parseBoolean(from.getDeprecated()));
+ }
+
+ return operation;
+ }
+
+ @Override
+ protected Tag mapTag(springfox.documentation.service.Tag from) {
+
+ if (from == null) {
+ return null;
+ }
+
+ Locale locale = LocaleContextHolder.getLocale();
+
+ Tag tag = new Tag();
+
+ tag.setVendorExtensions(vendorExtensionsMapper.mapExtensions(from.getVendorExtensions()));
+ tag.setName(messageSource.getMessage(from.getName(), null, from.getName(), locale));
+ tag.setDescription(from.getDescription());
+
+ return tag;
+ }
+
+
+ private ApiInfo fromResourceListingInfo(Documentation documentation) {
+
+ if (documentation == null) {
+ return null;
+ }
+ ResourceListing resourceListing = documentation.getResourceListing();
+ if (resourceListing == null) {
+ return null;
+ }
+ ApiInfo info = resourceListing.getInfo();
+ if (info == null) {
+ return null;
+ }
+ return info;
+ }
+
+ protected List tagSetToTagList(Set set) {
+
+ if (set == null) {
+ return null;
+ }
+
+ List list = new ArrayList(set.size());
+ for (springfox.documentation.service.Tag tag : set) {
+ list.add(mapTag(tag));
+ }
+
+ return list;
+ }
+
+ protected List stringSetToSchemeList(Set set) {
+ if (set == null) {
+ return null;
+ }
+
+ List list = new ArrayList(set.size());
+ for (String string : set) {
+ list.add(Enum.valueOf(Scheme.class, string));
+ }
+
+ return list;
+ }
+
+ protected List parameterListToParameterList(List list) {
+ if (list == null) {
+ return null;
+ }
+
+ List list1 = new ArrayList(list.size());
+
+ Locale locale = LocaleContextHolder.getLocale();
+
+ for (springfox.documentation.service.Parameter param : list) {
+ String description = messageSource.getMessage(param.getDescription(), null, param.getDescription(), locale);
+
+ springfox.documentation.service.Parameter parameter = new springfox.documentation.service.Parameter(param.getName(),description,param.getDefaultValue(),param.isRequired(),param.isAllowMultiple(),param.isAllowEmptyValue(),param.getModelRef(),param.getType(),param.getAllowableValues(),param.getParamType(),param.getParamAccess(),param.isHidden(),param.getPattern(),param.getCollectionFormat(),param.getOrder(),param.getScalarExample(),param.getExamples() ,param.getVendorExtentions());
+ list1.add(parameterMapper.mapParameter(parameter));
+ }
+
+ return list1;
+ }
+
+
+ Map modelsFromApiListings(Multimap apiListings) {
+ Map definitions = newTreeMap();
+ for (ApiListing each : apiListings.values()) {
+ definitions.putAll(each.getModels());
+ }
+ return modelMapper.mapModels(definitions);
+ }
+
+
+
+
+
+
+//
+//
+//
+// private static final VendorExtensionsMapper vendorMapper = new VendorExtensionsMapper();
+//
+//
+//
+// public Parameter mapParameter(springfox.documentation.service.Parameter source) {
+// Parameter bodyParameter = bodyParameter(source);
+// return SerializableParameterFactories.create(source).or(bodyParameter);
+// }
+//
+// private Parameter bodyParameter(springfox.documentation.service.Parameter source) {
+// BodyParameter parameter = new BodyParameter()
+// .description(source.getDescription())
+// .name(source.getName())
+// .schema(fromModelRef(source.getModelRef()));
+// parameter.setIn(source.getParamType());
+// parameter.setAccess(source.getParamAccess());
+// parameter.setPattern(source.getPattern());
+// parameter.setRequired(source.isRequired());
+// parameter.getVendorExtensions().putAll(vendorMapper.mapExtensions(source.getVendorExtentions()));
+// for (Map.Entry> each : source.getExamples().asMap().entrySet()) {
+// Optional example = FluentIterable.from(each.getValue()).first();
+// if (example.isPresent() && example.get().getValue() != null) {
+// parameter.addExample(each.getKey(), String.valueOf(example.get().getValue()));
+// }
+// }
+//
+// //TODO: swagger-core Body parameter does not have an enum property
+// return parameter;
+// }
+//
+// Model fromModelRef(ModelReference modelRef) {
+// if (modelRef.isCollection()) {
+// if (modelRef.getItemType().equals("byte")) {
+// ModelImpl baseModel = new ModelImpl();
+// baseModel.setType("string");
+// baseModel.setFormat("byte");
+// return maybeAddAllowableValuesToParameter(baseModel, modelRef.getAllowableValues());
+// } else if (modelRef.getItemType().equals("file")) {
+// ArrayModel files = new ArrayModel();
+// files.items(new FileProperty());
+// return files;
+// }
+// ModelReference itemModel = modelRef.itemModel().get();
+// return new ArrayModel()
+// .items(maybeAddAllowableValues(itemTypeProperty(itemModel), itemModel.getAllowableValues()));
+// }
+// if (modelRef.isMap()) {
+// ModelImpl baseModel = new ModelImpl();
+// ModelReference itemModel = modelRef.itemModel().get();
+// baseModel.additionalProperties(
+// maybeAddAllowableValues(
+// itemTypeProperty(itemModel),
+// itemModel.getAllowableValues()));
+// return baseModel;
+// }
+// if (isBaseType(modelRef.getType())) {
+// Property property = property(modelRef.getType());
+// ModelImpl baseModel = new ModelImpl();
+// baseModel.setType(property.getType());
+// baseModel.setFormat(property.getFormat());
+// return maybeAddAllowableValuesToParameter(baseModel, modelRef.getAllowableValues());
+//
+// }
+// return new RefModel(modelRef.getType());
+// }
+//
+//
+// private static class Properties {
+// private static final Map> typeFactory
+// = ImmutableMap.>builder()
+// .put("int", newInstanceOf(IntegerProperty.class))
+// .put("long", newInstanceOf(LongProperty.class))
+// .put("float", newInstanceOf(FloatProperty.class))
+// .put("double", newInstanceOf(DoubleProperty.class))
+// .put("string", newInstanceOf(StringProperty.class))
+// .put("boolean", newInstanceOf(BooleanProperty.class))
+// .put("date", newInstanceOf(DateProperty.class))
+// .put("date-time", newInstanceOf(DateTimeProperty.class))
+// .put("bigdecimal", newInstanceOf(DecimalProperty.class))
+// .put("biginteger", newInstanceOf(BaseIntegerProperty.class))
+// .put("uuid", newInstanceOf(UUIDProperty.class))
+// .put("object", newInstanceOf(ObjectProperty.class))
+// .put("byte", bytePropertyFactory())
+// .put("__file", filePropertyFactory())
+// .build();
+//
+// private Properties() {
+// throw new UnsupportedOperationException();
+// }
+//
+// public static Property property(final String typeName) {
+// String safeTypeName = nullToEmpty(typeName);
+// Function> propertyLookup
+// = forMap(typeFactory, voidOrRef(safeTypeName));
+// return propertyLookup.apply(safeTypeName.toLowerCase()).apply(safeTypeName);
+// }
+//
+// public static Property property(final ModelReference modelRef) {
+// if (modelRef.isMap()) {
+// return new MapProperty(property(modelRef.itemModel().get()));
+// } else if (modelRef.isCollection()) {
+// if ("byte".equals(modelRef.itemModel().transform(toTypeName()).or(""))) {
+// return new ByteArrayProperty();
+// }
+// return new ArrayProperty(
+// maybeAddAllowableValues(itemTypeProperty(modelRef.itemModel().get()), modelRef.getAllowableValues()));
+// }
+// return property(modelRef.getType());
+// }
+//
+// private static Function super ModelReference, String> toTypeName() {
+// return new Function() {
+// @Override
+// public String apply(ModelReference input) {
+// return input.getType();
+// }
+// };
+// }
+//
+// public static Property itemTypeProperty(ModelReference paramModel) {
+// if (paramModel.isCollection()) {
+// return new ArrayProperty(
+// maybeAddAllowableValues(itemTypeProperty(paramModel.itemModel().get()), paramModel.getAllowableValues()));
+// }
+// return property(paramModel.getType());
+// }
+//
+// private static Function newInstanceOf(final Class clazz) {
+// return new Function() {
+// @Override
+// public T apply(String input) {
+// try {
+// return clazz.newInstance();
+// } catch (Exception e) {
+// //This is bad! should never come here
+// throw new IllegalStateException(e);
+// }
+// }
+// };
+// }
+//
+// static Ordering defaultOrdering(Map properties) {
+// return Ordering.from(byPosition(properties)).compound(byName());
+// }
+//
+// private static Function voidOrRef(final String typeName) {
+// return new Function() {
+// @Override
+// public Property apply(String input) {
+// if (typeName.equalsIgnoreCase("void")) {
+// return null;
+// }
+// return new RefProperty(typeName);
+// }
+// };
+// }
+//
+// private static Function bytePropertyFactory() {
+// return new Function() {
+// @Override
+// public Property apply(String input) {
+// final IntegerProperty integerProperty = new IntegerProperty();
+// integerProperty.setFormat("int32");
+// integerProperty.setMaximum(BigDecimal.valueOf(Byte.MAX_VALUE));
+// integerProperty.setMinimum(BigDecimal.valueOf(Byte.MIN_VALUE));
+// return integerProperty;
+// }
+// };
+// }
+//
+// private static Function filePropertyFactory() {
+// return new Function() {
+// @Override
+// public Property apply(String input) {
+// return new FileProperty();
+// }
+// };
+// }
+//
+// private static Comparator byName() {
+// return new Comparator() {
+// @Override
+// public int compare(String first, String second) {
+// return first.compareTo(second);
+// }
+// };
+// }
+//
+// private static Comparator byPosition(final Map modelProperties) {
+// return new Comparator() {
+// @Override
+// public int compare(String first, String second) {
+// ModelProperty p1 = modelProperties.get(first);
+// ModelProperty p2 = modelProperties.get(second);
+// return Ints.compare(p1.getPosition(), p2.getPosition());
+// }
+// };
+// }
+//
+// static Predicate> voidProperties() {
+// return new Predicate>() {
+// @Override
+// public boolean apply(Map.Entry input) {
+// return isVoid(input.getValue().getType())
+// || collectionOfVoid(input.getValue().getType())
+// || arrayTypeOfVoid(input.getValue().getType().getArrayElementType());
+// }
+// };
+// }
+//
+// private static boolean arrayTypeOfVoid(ResolvedType arrayElementType) {
+// return arrayElementType != null && isVoid(arrayElementType);
+// }
+//
+// private static boolean collectionOfVoid(ResolvedType type) {
+// return isContainerType(type) && isVoid(collectionElementType(type));
+// }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/SwaggerConfig.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/SwaggerConfig.java
new file mode 100644
index 0000000000..5015438c19
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/SwaggerConfig.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.configuration;
+
+import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ *
+ * swager2 config class
+ *
+ */
+@Configuration
+@EnableSwagger2
+@EnableSwaggerBootstrapUI
+public class SwaggerConfig implements WebMvcConfigurer {
+
+ @Bean
+ public Docket createRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
+ .apis(RequestHandlerSelectors.basePackage("cn.escheduler.api.controller")).paths(PathSelectors.any())
+ .build();
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder().title("Easy Scheduler Api Docs").description("Easy Scheduler Api Docs")
+ .build();
+ }
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AccessTokenController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AccessTokenController.java
new file mode 100644
index 0000000000..efc6eb6647
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AccessTokenController.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.AccessTokenService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+/**
+ * access token controller
+ */
+@Api(tags = "ACCESS_TOKEN_TAG", position = 1)
+@RestController
+@RequestMapping("/access-token")
+public class AccessTokenController extends BaseController{
+
+
+ private static final Logger logger = LoggerFactory.getLogger(AccessTokenController.class);
+
+
+ @Autowired
+ private AccessTokenService accessTokenService;
+
+ /**
+ * create token
+ * @param loginUser
+ * @return
+ */
+ @ApiIgnore
+ @PostMapping(value = "/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createToken(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "expireTime") String expireTime,
+ @RequestParam(value = "token") String token){
+ logger.info("login user {}, create token , userId : {} , token expire time : {} , token : {}", loginUser.getUserName(),
+ userId,expireTime,token);
+
+ try {
+ Map result = accessTokenService.createToken(userId, expireTime, token);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(CREATE_ACCESS_TOKEN_ERROR.getMsg(),e);
+ return error(CREATE_ACCESS_TOKEN_ERROR.getCode(), CREATE_ACCESS_TOKEN_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * create token
+ * @param loginUser
+ * @return
+ */
+ @ApiIgnore
+ @PostMapping(value = "/generate")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result generateToken(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "expireTime") String expireTime){
+ logger.info("login user {}, generate token , userId : {} , token expire time : {}",loginUser,userId,expireTime);
+ try {
+ Map result = accessTokenService.generateToken(userId, expireTime);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(GENERATE_TOKEN_ERROR.getMsg(),e);
+ return error(GENERATE_TOKEN_ERROR.getCode(), GENERATE_TOKEN_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query access token list paging
+ *
+ * @param loginUser
+ * @param pageNo
+ * @param searchVal
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryAccessTokenList", notes= "QUERY_ACCESS_TOKEN_LIST_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", dataType ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType ="Int",example = "20")
+ })
+ @GetMapping(value="/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryAccessTokenList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize){
+ logger.info("login user {}, list access token paging, pageNo: {}, searchVal: {}, pageSize: {}",
+ loginUser.getUserName(),pageNo,searchVal,pageSize);
+ try{
+ Map result = checkPageParams(pageNo, pageSize);
+ if(result.get(Constants.STATUS) != Status.SUCCESS){
+ return returnDataListPaging(result);
+ }
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ result = accessTokenService.queryAccessTokenList(loginUser, searchVal, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getMsg(),e);
+ return error(QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getCode(),QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete access token by id
+ * @param loginUser
+ * @param id
+ * @return
+ */
+ @ApiIgnore
+ @PostMapping(value = "/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result delAccessTokenById(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id) {
+ logger.info("login user {}, delete access token, id: {},", loginUser.getUserName(), id);
+ try {
+ Map result = accessTokenService.delAccessTokenById(loginUser, id);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(DELETE_USER_BY_ID_ERROR.getMsg(),e);
+ return error(Status.DELETE_USER_BY_ID_ERROR.getCode(), Status.DELETE_USER_BY_ID_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * update token
+ * @param loginUser
+ * @return
+ */
+ @ApiIgnore
+ @PostMapping(value = "/update")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result updateToken(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "expireTime") String expireTime,
+ @RequestParam(value = "token") String token){
+ logger.info("login user {}, update token , userId : {} , token expire time : {} , token : {}", loginUser.getUserName(),
+ userId,expireTime,token);
+
+ try {
+ Map result = accessTokenService.updateToken(id,userId, expireTime, token);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(CREATE_ACCESS_TOKEN_ERROR.getMsg(),e);
+ return error(CREATE_ACCESS_TOKEN_ERROR.getCode(), CREATE_ACCESS_TOKEN_ERROR.getMsg());
+ }
+ }
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AlertGroupController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AlertGroupController.java
new file mode 100644
index 0000000000..d12415cdd6
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AlertGroupController.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+import org.apache.dolphinscheduler.api.service.AlertGroupService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.enums.AlertType;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * alert group controller
+ */
+@Api(tags = "ALERT_GROUP_TAG", position = 1)
+@RestController
+@RequestMapping("alert-group")
+public class AlertGroupController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(AlertGroupController.class);
+
+ @Autowired
+ private AlertGroupService alertGroupService;
+
+
+ /**
+ * create alert group
+ * @param loginUser
+ * @param groupName
+ * @param groupType
+ * @param desc
+ * @return
+ */
+ @ApiOperation(value = "createAlertgroup", notes= "CREATE_ALERT_GROUP_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "groupName", value = "GROUP_NAME", required = true, dataType = "String"),
+ @ApiImplicitParam(name = "groupType", value = "GROUP_TYPE", required = true, dataType ="AlertType"),
+ @ApiImplicitParam(name = "desc", value = "DESC", dataType ="String")
+ })
+ @PostMapping(value = "/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createAlertgroup(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "groupName") String groupName,
+ @RequestParam(value = "groupType") AlertType groupType,
+ @RequestParam(value = "desc",required = false) String desc) {
+ logger.info("loginUser user {}, create alertgroup, groupName: {}, groupType: {}, desc: {}",
+ loginUser.getUserName(), groupName, groupType,desc);
+ try {
+ Map result = alertGroupService.createAlertgroup(loginUser, groupName, groupType,desc);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.CREATE_ALERT_GROUP_ERROR.getMsg(),e);
+ return error(Status.CREATE_ALERT_GROUP_ERROR.getCode(), Status.CREATE_ALERT_GROUP_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * alert group list
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "list", notes= "QUERY_ALERT_GROUP_LIST_NOTES")
+ @GetMapping(value = "/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result list(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
+ logger.info("login user {}, query all alertGroup",
+ loginUser.getUserName());
+ try{
+ HashMap result = alertGroupService.queryAlertgroup();
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_ALL_ALERTGROUP_ERROR.getMsg(),e);
+ return error(Status.QUERY_ALL_ALERTGROUP_ERROR.getCode(), Status.QUERY_ALL_ALERTGROUP_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * paging query alarm group list
+ *
+ * @param loginUser
+ * @param pageNo
+ * @param searchVal
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryTaskListPaging", notes= "QUERY_TASK_INSTANCE_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", type ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType = "Int", example = "20")
+ })
+ @GetMapping(value="/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result listPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize){
+ logger.info("login user {}, list paging, pageNo: {}, searchVal: {}, pageSize: {}",
+ loginUser.getUserName(),pageNo,searchVal,pageSize);
+ try{
+ Map result = checkPageParams(pageNo, pageSize);
+ if(result.get(Constants.STATUS) != Status.SUCCESS){
+ return returnDataListPaging(result);
+ }
+
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ result = alertGroupService.listPaging(loginUser, searchVal, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.LIST_PAGING_ALERT_GROUP_ERROR.getMsg(),e);
+ return error(Status.LIST_PAGING_ALERT_GROUP_ERROR.getCode(), Status.LIST_PAGING_ALERT_GROUP_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * updateProcessInstance alert group
+ * @param loginUser
+ * @param id
+ * @param groupName
+ * @param groupType
+ * @param desc
+ * @return
+ */
+ @ApiOperation(value = "updateAlertgroup", notes= "UPDATE_ALERT_GROUP_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "ALERT_GROUP_ID", required = true, dataType = "Int",example = "100"),
+ @ApiImplicitParam(name = "groupName", value = "GROUP_NAME", required = true, dataType = "String"),
+ @ApiImplicitParam(name = "groupType", value = "GROUP_TYPE", required = true, dataType ="AlertType"),
+ @ApiImplicitParam(name = "desc", value = "DESC", dataType ="String")
+ })
+ @PostMapping(value = "/update")
+ @ResponseStatus(HttpStatus.OK)
+ public Result updateAlertgroup(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id,
+ @RequestParam(value = "groupName") String groupName,
+ @RequestParam(value = "groupType") AlertType groupType,
+ @RequestParam(value = "desc",required = false) String desc) {
+ logger.info("login user {}, updateProcessInstance alertgroup, groupName: {}, groupType: {}, desc: {}",
+ loginUser.getUserName(), groupName, groupType,desc);
+ try {
+ Map result = alertGroupService.updateAlertgroup(loginUser, id, groupName, groupType, desc);
+ return returnDataList(result);
+
+ }catch (Exception e){
+ logger.error(Status.UPDATE_ALERT_GROUP_ERROR.getMsg(),e);
+ return error(Status.UPDATE_ALERT_GROUP_ERROR.getCode(), Status.UPDATE_ALERT_GROUP_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete alert group by id
+ * @param loginUser
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "delAlertgroupById", notes= "DELETE_ALERT_GROUP_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "ALERT_GROUP_ID", required = true, dataType = "Int",example = "100")
+ })
+ @PostMapping(value = "/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result delAlertgroupById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id) {
+ logger.info("login user {}, delete AlertGroup, id: {},", loginUser.getUserName(), id);
+ try {
+ Map result = alertGroupService.delAlertgroupById(loginUser, id);
+ return returnDataList(result);
+
+ }catch (Exception e){
+ logger.error(Status.DELETE_ALERT_GROUP_ERROR.getMsg(),e);
+ return error(Status.DELETE_ALERT_GROUP_ERROR.getCode(), Status.DELETE_ALERT_GROUP_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * check alert group exist
+ * @param loginUser
+ * @param groupName
+ * @return
+ */
+ @ApiOperation(value = "verifyGroupName", notes= "VERIFY_ALERT_GROUP_NAME_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "groupName", value = "GROUP_NAME", required = true, dataType = "String"),
+ })
+ @GetMapping(value = "/verify-group-name")
+ @ResponseStatus(HttpStatus.OK)
+ public Result verifyGroupName(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="groupName") String groupName
+ ) {
+ logger.info("login user {}, verfiy group name: {}",
+ loginUser.getUserName(),groupName);
+
+ return alertGroupService.verifyGroupName(loginUser, groupName);
+ }
+
+ /**
+ * grant user
+ *
+ * @param loginUser
+ * @param userIds
+ * @return
+ */
+ @ApiOperation(value = "grantUser", notes= "GRANT_ALERT_GROUP_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "ALERT_GROUP_ID", required = true, dataType = "Int",example = "100"),
+ @ApiImplicitParam(name = "userIds", value = "USER_IDS", required = true, dataType = "String")
+ })
+ @PostMapping(value = "/grant-user")
+ @ResponseStatus(HttpStatus.OK)
+ public Result grantUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "alertgroupId") int alertgroupId,
+ @RequestParam(value = "userIds") String userIds) {
+ logger.info("login user {}, grant user, alertGroupId: {},userIds : {}", loginUser.getUserName(), alertgroupId,userIds);
+ try {
+ Map result = alertGroupService.grantUser(loginUser, alertgroupId, userIds);
+ return returnDataList(result);
+
+ }catch (Exception e){
+ logger.error(Status.ALERT_GROUP_GRANT_USER_ERROR.getMsg(),e);
+ return error(Status.ALERT_GROUP_GRANT_USER_ERROR.getCode(), Status.ALERT_GROUP_GRANT_USER_ERROR.getMsg());
+ }
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/BaseController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/BaseController.java
new file mode 100644
index 0000000000..75bea3e4b6
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/BaseController.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.PageInfo;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.Resource;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.dolphinscheduler.common.Constants.*;
+
+/**
+ * base controller
+ */
+public class BaseController {
+
+ /**
+ * check params
+ *
+ * @param pageNo
+ * @param pageSize
+ * @return
+ */
+ public Map checkPageParams(int pageNo, int pageSize) {
+ Map result = new HashMap<>(2);
+ Status resultEnum = Status.SUCCESS;
+ String msg = Status.SUCCESS.getMsg();
+ if (pageNo <= 0) {
+ resultEnum = Status.REQUEST_PARAMS_NOT_VALID_ERROR;
+ msg = MessageFormat.format(Status.REQUEST_PARAMS_NOT_VALID_ERROR.getMsg(), Constants.PAGE_NUMBER);
+ } else if (pageSize <= 0) {
+ resultEnum = Status.REQUEST_PARAMS_NOT_VALID_ERROR;
+ msg = MessageFormat.format(Status.REQUEST_PARAMS_NOT_VALID_ERROR.getMsg(), Constants.PAGE_SIZE);
+ }
+ result.put(Constants.STATUS, resultEnum);
+ result.put(Constants.MSG, msg);
+ return result;
+ }
+
+ /**
+ * get ip address in the http request
+ *
+ * @param request
+ * @return client ip address
+ */
+ public static String getClientIpAddress(HttpServletRequest request) {
+ String clientIp = request.getHeader(HTTP_X_FORWARDED_FOR);
+
+ if (StringUtils.isNotEmpty(clientIp) && !StringUtils.equalsIgnoreCase(HTTP_HEADER_UNKNOWN, clientIp)) {
+ int index = clientIp.indexOf(COMMA);
+ if (index != -1) {
+ return clientIp.substring(0, index);
+ } else {
+ return clientIp;
+ }
+ }
+
+ clientIp = request.getHeader(HTTP_X_REAL_IP);
+ if (StringUtils.isNotEmpty(clientIp) && !StringUtils.equalsIgnoreCase(HTTP_HEADER_UNKNOWN, clientIp)) {
+ return clientIp;
+ }
+
+ return request.getRemoteAddr();
+ }
+
+ /**
+ * return data list
+ *
+ * @param result
+ * @return
+ */
+ public Result returnDataList(Map result) {
+ Status status = (Status) result.get(Constants.STATUS);
+ if (status == Status.SUCCESS) {
+ String msg = Status.SUCCESS.getMsg();
+ Object datalist = result.get(Constants.DATA_LIST);
+ return success(msg, datalist);
+ } else {
+ Integer code = status.getCode();
+ String msg = (String) result.get(Constants.MSG);
+ return error(code, msg);
+ }
+ }
+
+ /**
+ * return data list with paging
+ * @param result
+ * @return
+ */
+ public Result returnDataListPaging(Map result) {
+ Status status = (Status) result.get(Constants.STATUS);
+ if (status == Status.SUCCESS) {
+ result.put(Constants.MSG, Status.SUCCESS.getMsg());
+ PageInfo pageInfo = (PageInfo) result.get(Constants.DATA_LIST);
+ return success(pageInfo.getLists(), pageInfo.getCurrentPage(), pageInfo.getTotalCount(),
+ pageInfo.getTotalPage());
+ } else {
+ Integer code = status.getCode();
+ String msg = (String) result.get(Constants.MSG);
+ return error(code, msg);
+ }
+ }
+
+ /**
+ * success
+ *
+ * @return
+ */
+ public Result success() {
+ Result result = new Result();
+ result.setCode(Status.SUCCESS.getCode());
+ result.setMsg(Status.SUCCESS.getMsg());
+
+ return result;
+ }
+
+ /**
+ * success does not need to return data
+ *
+ * @param msg
+ * @return
+ */
+ public Result success(String msg) {
+ Result result = new Result();
+ result.setCode(Status.SUCCESS.getCode());
+ result.setMsg(msg);
+
+ return result;
+ }
+
+ /**
+ * return data no paging
+ *
+ * @param msg
+ * @param list
+ * @return
+ */
+ public Result success(String msg, Object list) {
+ Result result = getResult(msg, list);
+ return result;
+ }
+
+ /**
+ * return data no paging
+ *
+ * @param list
+ * @return
+ */
+ public Result success(Object list) {
+ Result result = getResult(Status.SUCCESS.getMsg(), list);
+ return result;
+ }
+
+ /**
+ * return the data use Map format, for example, passing the value of key, value, passing a value
+ * eg. "/user/add" then return user name: zhangsan
+ *
+ * @param msg
+ * @param object
+ * @return
+ */
+ public Result success(String msg, Map object) {
+ Result result = getResult(msg, object);
+ return result;
+ }
+
+ /**
+ * return data with paging
+ *
+ * @param totalList
+ * @param currentPage
+ * @param total
+ * @return
+ */
+ public Result success(Object totalList, Integer currentPage,
+ Integer total, Integer totalPage) {
+ Result result = new Result();
+ result.setCode(Status.SUCCESS.getCode());
+ result.setMsg(Status.SUCCESS.getMsg());
+
+ Map map = new HashMap<>(4);
+ map.put(Constants.TOTAL_LIST, totalList);
+ map.put(Constants.CURRENT_PAGE, currentPage);
+ map.put(Constants.TOTAL_PAGE, totalPage);
+ map.put(Constants.TOTAL, total);
+ result.setData(map);
+ return result;
+ }
+
+ /**
+ * error handle
+ *
+ * @param code
+ * @param msg
+ * @return
+ */
+ public Result error(Integer code, String msg) {
+ Result result = new Result();
+ result.setCode(code);
+ result.setMsg(msg);
+ return result;
+ }
+
+ /**
+ * put message to map
+ *
+ * @param result
+ * @param status
+ * @param statusParams
+ */
+ protected void putMsg(Map result, Status status, Object... statusParams) {
+ result.put(Constants.STATUS, status);
+ if (statusParams != null && statusParams.length > 0) {
+ result.put(Constants.MSG, MessageFormat.format(status.getMsg(), statusParams));
+ } else {
+ result.put(Constants.MSG, status.getMsg());
+ }
+ }
+
+ /**
+ * put message to result object
+ *
+ * @param result
+ * @param status
+ */
+ protected void putMsg(Result result, Status status, Object... statusParams) {
+ result.setCode(status.getCode());
+
+ if (statusParams != null && statusParams.length > 0) {
+ result.setMsg(MessageFormat.format(status.getMsg(), statusParams));
+ } else {
+ result.setMsg(status.getMsg());
+ }
+
+ }
+
+ /**
+ * get result
+ * @param msg
+ * @param list
+ * @return
+ */
+ private Result getResult(String msg, Object list) {
+ Result result = new Result();
+ result.setCode(Status.SUCCESS.getCode());
+ result.setMsg(msg);
+
+ result.setData(list);
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataAnalysisController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataAnalysisController.java
new file mode 100644
index 0000000000..76b4f244b7
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataAnalysisController.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.service.DataAnalysisService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+/**
+ * data analysis controller
+ */
+@Api(tags = "DATA_ANALYSIS_TAG", position = 1)
+@RestController
+@RequestMapping("projects/analysis")
+public class DataAnalysisController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(DataAnalysisController.class);
+
+
+ @Autowired
+ DataAnalysisService dataAnalysisService;
+
+
+ /**
+ * statistical task instance status data
+ *
+ * @param loginUser
+ * @param projectId
+ * @return
+ */
+ @ApiOperation(value = "countTaskState", notes= "COUNT_TASK_STATE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "startDate", value = "START_DATE", dataType = "String"),
+ @ApiImplicitParam(name = "endDate", value = "END_DATE", dataType ="String"),
+ @ApiImplicitParam(name = "projectId", value = "PROJECT_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value="/task-state-count")
+ @ResponseStatus(HttpStatus.OK)
+ public Result countTaskState(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value="startDate", required=false) String startDate,
+ @RequestParam(value="endDate", required=false) String endDate,
+ @RequestParam(value="projectId", required=false, defaultValue = "0") int projectId){
+ try{
+ logger.info("count task state, user:{}, start date: {}, end date:{}, project id {}",
+ loginUser.getUserName(), startDate, endDate, projectId);
+ Map result = dataAnalysisService.countTaskStateByProject(loginUser,projectId, startDate, endDate);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.TASK_INSTANCE_STATE_COUNT_ERROR.getMsg(),e);
+ return error(Status.TASK_INSTANCE_STATE_COUNT_ERROR.getCode(), Status.TASK_INSTANCE_STATE_COUNT_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * statistical process instance status data
+ *
+ * @param loginUser
+ * @param projectId
+ * @return
+ */
+ @ApiOperation(value = "countProcessInstanceState", notes= "COUNT_PROCESS_INSTANCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "startDate", value = "START_DATE", dataType = "String"),
+ @ApiImplicitParam(name = "endDate", value = "END_DATE", dataType ="String"),
+ @ApiImplicitParam(name = "projectId", value = "PROJECT_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value="/process-state-count")
+ @ResponseStatus(HttpStatus.OK)
+ public Result countProcessInstanceState(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value="startDate", required=false) String startDate,
+ @RequestParam(value="endDate", required=false) String endDate,
+ @RequestParam(value="projectId", required=false, defaultValue = "0") int projectId){
+ try{
+ logger.info("count process instance state, user:{}, start date: {}, end date:{}, project id",
+ loginUser.getUserName(), startDate, endDate, projectId);
+ Map result = dataAnalysisService.countProcessInstanceStateByProject(loginUser, projectId, startDate, endDate);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.COUNT_PROCESS_INSTANCE_STATE_ERROR.getMsg(),e);
+ return error(Status.COUNT_PROCESS_INSTANCE_STATE_ERROR.getCode(), Status.COUNT_PROCESS_INSTANCE_STATE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * statistics the process definition quantities of certain person
+ *
+ * @param loginUser
+ * @param projectId
+ * @return
+ */
+ @ApiOperation(value = "countDefinitionByUser", notes= "COUNT_PROCESS_DEFINITION_BY_USER_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "projectId", value = "PROJECT_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value="/define-user-count")
+ @ResponseStatus(HttpStatus.OK)
+ public Result countDefinitionByUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value="projectId", required=false, defaultValue = "0") int projectId){
+ try{
+ logger.info("count process definition , user:{}, project id",
+ loginUser.getUserName(), projectId);
+ Map result = dataAnalysisService.countDefinitionByUser(loginUser, projectId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.COUNT_PROCESS_DEFINITION_USER_ERROR.getMsg(),e);
+ return error(Status.COUNT_PROCESS_DEFINITION_USER_ERROR.getCode(), Status.COUNT_PROCESS_DEFINITION_USER_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * statistical command status data
+ *
+ * @param loginUser
+ * @param projectId
+ * @return
+ */
+ @ApiOperation(value = "countCommandState", notes= "COUNT_COMMAND_STATE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "startDate", value = "START_DATE", dataType = "String"),
+ @ApiImplicitParam(name = "endDate", value = "END_DATE", dataType ="String"),
+ @ApiImplicitParam(name = "projectId", value = "PROJECT_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value="/command-state-count")
+ @ResponseStatus(HttpStatus.OK)
+ public Result countCommandState(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value="startDate", required=false) String startDate,
+ @RequestParam(value="endDate", required=false) String endDate,
+ @RequestParam(value="projectId", required=false, defaultValue = "0") int projectId){
+ try{
+ logger.info("count command state, user:{}, start date: {}, end date:{}, project id {}",
+ loginUser.getUserName(), startDate, endDate, projectId);
+ Map result = dataAnalysisService.countCommandState(loginUser, projectId, startDate, endDate);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.COMMAND_STATE_COUNT_ERROR.getMsg(),e);
+ return error(Status.COMMAND_STATE_COUNT_ERROR.getCode(), Status.COMMAND_STATE_COUNT_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * queue count
+ *
+ * @param loginUser
+ * @param projectId
+ * @return
+ */
+ @ApiOperation(value = "countQueueState", notes= "COUNT_QUEUE_STATE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "startDate", value = "START_DATE", dataType = "String"),
+ @ApiImplicitParam(name = "endDate", value = "END_DATE", dataType ="String"),
+ @ApiImplicitParam(name = "projectId", value = "PROJECT_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value="/queue-count")
+ @ResponseStatus(HttpStatus.OK)
+ public Result countQueueState(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value="projectId", required=false, defaultValue = "0") int projectId){
+ try{
+ logger.info("count command state, user:{}, start date: {}, end date:{}, project id {}",
+ loginUser.getUserName(), projectId);
+ Map result = dataAnalysisService.countQueueState(loginUser, projectId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.QUEUE_COUNT_ERROR.getMsg(),e);
+ return error(Status.QUEUE_COUNT_ERROR.getCode(), Status.QUEUE_COUNT_ERROR.getMsg());
+ }
+ }
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataSourceController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataSourceController.java
new file mode 100644
index 0000000000..1f9a30098f
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataSourceController.java
@@ -0,0 +1,458 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.DataSourceService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.enums.DbType;
+import org.apache.dolphinscheduler.common.utils.CommonUtils;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+/**
+ * data source controller
+ */
+@Api(tags = "DATA_SOURCE_TAG", position = 3)
+@RestController
+@RequestMapping("datasources")
+public class DataSourceController extends BaseController {
+
+ private static final Logger logger = LoggerFactory.getLogger(DataSourceController.class);
+
+ @Autowired
+ private DataSourceService dataSourceService;
+
+ /**
+ * create data source
+ * @param loginUser
+ * @param name
+ * @param note
+ * @param type
+ * @param host
+ * @param port
+ * @param database
+ * @param principal
+ * @param userName
+ * @param password
+ * @param other
+ * @return
+ */
+ @ApiOperation(value = "createDataSource", notes= "CREATE_DATA_SOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name", value = "DATA_SOURCE_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "note", value = "DATA_SOURCE_NOTE", dataType = "String"),
+ @ApiImplicitParam(name = "type", value = "DB_TYPE", required = true,dataType ="DbType"),
+ @ApiImplicitParam(name = "host", value = "DATA_SOURCE_HOST",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "port", value = "DATA_SOURCE_PORT",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "database", value = "DATABASE_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "userName", value = "USER_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "password", value = "PASSWORD", dataType ="String"),
+ @ApiImplicitParam(name = "other", value = "DATA_SOURCE_OTHER", dataType ="String")
+ })
+ @PostMapping(value = "/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createDataSource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("name") String name,
+ @RequestParam(value = "note", required = false) String note,
+ @RequestParam(value = "type") DbType type,
+ @RequestParam(value = "host") String host,
+ @RequestParam(value = "port") String port,
+ @RequestParam(value = "database") String database,
+ @RequestParam(value = "principal") String principal,
+ @RequestParam(value = "userName") String userName,
+ @RequestParam(value = "password") String password,
+ @RequestParam(value = "other") String other) {
+ logger.info("login user {} create datasource name: {}, note: {}, type: {}, host: {},port: {},database : {},principal: {},userName : {} other: {}",
+ loginUser.getUserName(), name, note, type, host,port,database,principal,userName,other);
+ try {
+ String parameter = dataSourceService.buildParameter(name, note, type, host, port, database,principal,userName, password, other);
+ Map result = dataSourceService.createDataSource(loginUser, name, note, type, parameter);
+ return returnDataList(result);
+
+ } catch (Exception e) {
+ logger.error(CREATE_DATASOURCE_ERROR.getMsg(),e);
+ return error(Status.CREATE_DATASOURCE_ERROR.getCode(), Status.CREATE_DATASOURCE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * updateProcessInstance data source
+ *
+ * @param loginUser
+ * @param name
+ * @param note
+ * @param type
+ * @param other
+ * @return
+ */
+ @ApiOperation(value = "updateDataSource", notes= "UPDATE_DATA_SOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "DATA_SOURCE_ID", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "name", value = "DATA_SOURCE_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "note", value = "DATA_SOURCE_NOTE", dataType = "String"),
+ @ApiImplicitParam(name = "type", value = "DB_TYPE", required = true,dataType ="DbType"),
+ @ApiImplicitParam(name = "host", value = "DATA_SOURCE_HOST",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "port", value = "DATA_SOURCE_PORT",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "database", value = "DATABASE_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "userName", value = "USER_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "password", value = "PASSWORD", dataType ="String"),
+ @ApiImplicitParam(name = "other", value = "DATA_SOURCE_OTHER", dataType ="String")
+ })
+ @PostMapping(value = "/update")
+ @ResponseStatus(HttpStatus.OK)
+ public Result updateDataSource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("id") int id,
+ @RequestParam("name") String name,
+ @RequestParam(value = "note", required = false) String note,
+ @RequestParam(value = "type") DbType type,
+ @RequestParam(value = "host") String host,
+ @RequestParam(value = "port") String port,
+ @RequestParam(value = "database") String database,
+ @RequestParam(value = "principal") String principal,
+ @RequestParam(value = "userName") String userName,
+ @RequestParam(value = "password") String password,
+ @RequestParam(value = "other") String other) {
+ logger.info("login user {} updateProcessInstance datasource name: {}, note: {}, type: {}, other: {}",
+ loginUser.getUserName(), name, note, type, other);
+ try {
+ String parameter = dataSourceService.buildParameter(name, note, type, host, port, database,principal, userName, password, other);
+ Map dataSource = dataSourceService.updateDataSource(id, loginUser, name, note, type, parameter);
+ return returnDataList(dataSource);
+ } catch (Exception e) {
+ logger.error(UPDATE_DATASOURCE_ERROR.getMsg(),e);
+ return error(UPDATE_DATASOURCE_ERROR.getCode(), UPDATE_DATASOURCE_ERROR.getMsg());
+ }
+
+
+ }
+
+ /**
+ * query data source
+ *
+ * @param loginUser
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "queryDataSource", notes= "QUERY_DATA_SOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "DATA_SOURCE_ID", required = true, dataType ="Int", example = "100")
+
+ })
+ @PostMapping(value = "/update-ui")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryDataSource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("id") int id) {
+ logger.info("login user {}, query datasource: {}",
+ loginUser.getUserName(), id);
+ try {
+ Map result = dataSourceService.queryDataSource(id);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(QUERY_DATASOURCE_ERROR.getMsg(),e);
+ return error(Status.QUERY_DATASOURCE_ERROR.getCode(), Status.QUERY_DATASOURCE_ERROR.getMsg());
+ }
+
+
+ }
+
+ /**
+ * query datasouce by type
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryDataSourceList", notes= "QUERY_DATA_SOURCE_LIST_BY_TYPE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "DB_TYPE", required = true,dataType ="DbType")
+ })
+ @GetMapping(value = "/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryDataSourceList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("type") DbType type) {
+ try {
+ Map result = dataSourceService.queryDataSourceList(loginUser, type.ordinal());
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(QUERY_DATASOURCE_ERROR.getMsg(),e);
+ return error(Status.QUERY_DATASOURCE_ERROR.getCode(), Status.QUERY_DATASOURCE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query datasource with paging
+ *
+ * @param loginUser
+ * @param searchVal
+ * @param pageNo
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryDataSourceListPaging", notes= "QUERY_DATA_SOURCE_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", dataType ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType ="Int",example = "20")
+ })
+ @GetMapping(value = "/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryDataSourceListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam("pageSize") Integer pageSize) {
+ try {
+ Map result = checkPageParams(pageNo, pageSize);
+ if (result.get(Constants.STATUS) != Status.SUCCESS) {
+ return returnDataListPaging(result);
+ }
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ result = dataSourceService.queryDataSourceListPaging(loginUser, searchVal, pageNo, pageSize);
+ return returnDataListPaging(result);
+ } catch (Exception e) {
+ logger.error(QUERY_DATASOURCE_ERROR.getMsg(),e);
+ return error(QUERY_DATASOURCE_ERROR.getCode(), QUERY_DATASOURCE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * connec datasource
+ *
+ * @param loginUser
+ * @param name
+ * @param note
+ * @param type
+ * @param other
+ * @return
+ */
+ @ApiOperation(value = "connectDataSource", notes= "CONNECT_DATA_SOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name", value = "DATA_SOURCE_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "note", value = "DATA_SOURCE_NOTE", dataType = "String"),
+ @ApiImplicitParam(name = "type", value = "DB_TYPE", required = true,dataType ="DbType"),
+ @ApiImplicitParam(name = "host", value = "DATA_SOURCE_HOST",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "port", value = "DATA_SOURCE_PORT",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "database", value = "DATABASE_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "userName", value = "USER_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "password", value = "PASSWORD", dataType ="String"),
+ @ApiImplicitParam(name = "other", value = "DATA_SOURCE_OTHER", dataType ="String")
+ })
+ @PostMapping(value = "/connect")
+ @ResponseStatus(HttpStatus.OK)
+ public Result connectDataSource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("name") String name,
+ @RequestParam(value = "note", required = false) String note,
+ @RequestParam(value = "type") DbType type,
+ @RequestParam(value = "host") String host,
+ @RequestParam(value = "port") String port,
+ @RequestParam(value = "database") String database,
+ @RequestParam(value = "principal") String principal,
+ @RequestParam(value = "userName") String userName,
+ @RequestParam(value = "password") String password,
+ @RequestParam(value = "other") String other) {
+ logger.info("login user {}, connect datasource: {} failure, note: {}, type: {}, other: {}",
+ loginUser.getUserName(), name, note, type, other);
+ try {
+ String parameter = dataSourceService.buildParameter(name, note, type, host, port, database,principal,userName, password, other);
+ Boolean isConnection = dataSourceService.checkConnection(type, parameter);
+ Result result = new Result();
+
+ if (isConnection) {
+ putMsg(result, SUCCESS);
+ } else {
+ putMsg(result, CONNECT_DATASOURCE_FAILURE);
+ }
+ return result;
+ } catch (Exception e) {
+ logger.error(CONNECT_DATASOURCE_FAILURE.getMsg(),e);
+ return error(CONNECT_DATASOURCE_FAILURE.getCode(), CONNECT_DATASOURCE_FAILURE.getMsg());
+ }
+ }
+
+ /**
+ * connection test
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "connectionTest", notes= "CONNECT_DATA_SOURCE_TEST_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "DATA_SOURCE_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/connect-by-id")
+ @ResponseStatus(HttpStatus.OK)
+ public Result connectionTest(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("id") int id) {
+ logger.info("connection test, login user:{}, id:{}", loginUser.getUserName(), id);
+
+ try {
+ Boolean isConnection = dataSourceService.connectionTest(loginUser, id);
+ Result result = new Result();
+
+ if (isConnection) {
+ putMsg(result, SUCCESS);
+ } else {
+ putMsg(result, CONNECTION_TEST_FAILURE);
+ }
+ return result;
+ } catch (Exception e) {
+ logger.error(CONNECTION_TEST_FAILURE.getMsg(),e);
+ return error(CONNECTION_TEST_FAILURE.getCode(), CONNECTION_TEST_FAILURE.getMsg());
+ }
+
+ }
+
+ /**
+ * delete datasource by id
+ *
+ * @param loginUser
+ * @param id datasource id
+ * @return
+ */
+ @ApiOperation(value = "delete", notes= "DELETE_DATA_SOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "DATA_SOURCE_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result delete(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("id") int id) {
+ try {
+ logger.info("delete datasource,login user:{}, id:{}", loginUser.getUserName(), id);
+ return dataSourceService.delete(loginUser, id);
+ } catch (Exception e) {
+ logger.error(DELETE_DATA_SOURCE_FAILURE.getMsg(),e);
+ return error(DELETE_DATA_SOURCE_FAILURE.getCode(), DELETE_DATA_SOURCE_FAILURE.getMsg());
+ }
+ }
+
+ /**
+ * verify datasource name
+ *
+ * @param loginUser
+ * @param name
+ * @return
+ */
+ @ApiOperation(value = "verifyDataSourceName", notes= "VERIFY_DATA_SOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name", value = "DATA_SOURCE_NAME", required = true, dataType ="String")
+ })
+ @GetMapping(value = "/verify-name")
+ @ResponseStatus(HttpStatus.OK)
+ public Result verifyDataSourceName(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "name") String name
+ ) {
+ logger.info("login user {}, verfiy datasource name: {}",
+ loginUser.getUserName(), name);
+
+ try {
+ return dataSourceService.verifyDataSourceName(loginUser, name);
+ } catch (Exception e) {
+ logger.error(VERFIY_DATASOURCE_NAME_FAILURE.getMsg(),e);
+ return error(VERFIY_DATASOURCE_NAME_FAILURE.getCode(), VERFIY_DATASOURCE_NAME_FAILURE.getMsg());
+ }
+ }
+
+
+
+ /**
+ * unauthorized datasource
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "unauthDatasource", notes= "UNAUTHORIZED_DATA_SOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/unauth-datasource")
+ @ResponseStatus(HttpStatus.OK)
+ public Result unauthDatasource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ try {
+ logger.info("unauthorized datasource, login user:{}, unauthorized userId:{}",
+ loginUser.getUserName(), userId);
+ Map result = dataSourceService.unauthDatasource(loginUser, userId);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(UNAUTHORIZED_DATASOURCE.getMsg(),e);
+ return error(UNAUTHORIZED_DATASOURCE.getCode(), UNAUTHORIZED_DATASOURCE.getMsg());
+ }
+ }
+
+
+ /**
+ * authorized datasource
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "authedDatasource", notes= "AUTHORIZED_DATA_SOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/authed-datasource")
+ @ResponseStatus(HttpStatus.OK)
+ public Result authedDatasource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ try {
+ logger.info("authorized data source, login user:{}, authorized useId:{}",
+ loginUser.getUserName(), userId);
+ Map result = dataSourceService.authedDatasource(loginUser, userId);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(AUTHORIZED_DATA_SOURCE.getMsg(),e);
+ return error(AUTHORIZED_DATA_SOURCE.getCode(), AUTHORIZED_DATA_SOURCE.getMsg());
+ }
+ }
+
+ /**
+ * get user info
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "getKerberosStartupState", notes= "GET_USER_INFO_NOTES")
+ @GetMapping(value="/kerberos-startup-state")
+ @ResponseStatus(HttpStatus.OK)
+ public Result getKerberosStartupState(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser){
+ logger.info("login user {},get kerberos startup state : {}", loginUser.getUserName());
+ try{
+ // if upload resource is HDFS and kerberos startup is true , else false
+ return success(Status.SUCCESS.getMsg(), CommonUtils.getKerberosStartupState());
+ }catch (Exception e){
+ logger.error(KERBEROS_STARTUP_STATE.getMsg(),e);
+ return error(Status.KERBEROS_STARTUP_STATE.getCode(), Status.KERBEROS_STARTUP_STATE.getMsg());
+ }
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ExecutorController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ExecutorController.java
new file mode 100644
index 0000000000..68b6985ffe
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ExecutorController.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.ExecuteType;
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.ExecutorService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.*;
+import org.apache.dolphinscheduler.common.enums.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+
+/**
+ * execute process controller
+ */
+@Api(tags = "PROCESS_INSTANCE_EXECUTOR_TAG", position = 1)
+@RestController
+@RequestMapping("projects/{projectName}/executors")
+public class ExecutorController extends BaseController {
+
+ private static final Logger logger = LoggerFactory.getLogger(ExecutorController.class);
+
+ @Autowired
+ private ExecutorService execService;
+
+ /**
+ * execute process instance
+ */
+ @ApiOperation(value = "startProcessInstance", notes= "RUN_PROCESS_INSTANCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "scheduleTime", value = "SCHEDULE_TIME", required = true, dataType = "String"),
+ @ApiImplicitParam(name = "failureStrategy", value = "FAILURE_STRATEGY", required = true, dataType ="FailureStrategy"),
+ @ApiImplicitParam(name = "startNodeList", value = "START_NODE_LIST", dataType ="String"),
+ @ApiImplicitParam(name = "taskDependType", value = "TASK_DEPEND_TYPE", dataType ="TaskDependType"),
+ @ApiImplicitParam(name = "execType", value = "COMMAND_TYPE", dataType ="CommandType"),
+ @ApiImplicitParam(name = "warningType", value = "WARNING_TYPE",required = true, dataType ="WarningType"),
+ @ApiImplicitParam(name = "warningGroupId", value = "WARNING_GROUP_ID",required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "receivers", value = "RECEIVERS",dataType ="String" ),
+ @ApiImplicitParam(name = "receiversCc", value = "RECEIVERS_CC",dataType ="String" ),
+ @ApiImplicitParam(name = "runMode", value = "RUN_MODE",dataType ="RunMode" ),
+ @ApiImplicitParam(name = "processInstancePriority", value = "PROCESS_INSTANCE_PRIORITY", required = true, dataType = "Priority" ),
+ @ApiImplicitParam(name = "workerGroupId", value = "WORKER_GROUP_ID", dataType = "Int",example = "100"),
+ @ApiImplicitParam(name = "timeout", value = "TIMEOUT", dataType = "Int",example = "100"),
+ })
+ @PostMapping(value = "start-process-instance")
+ @ResponseStatus(HttpStatus.OK)
+ public Result startProcessInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam(value = "processDefinitionId") int processDefinitionId,
+ @RequestParam(value = "scheduleTime", required = false) String scheduleTime,
+ @RequestParam(value = "failureStrategy", required = true) FailureStrategy failureStrategy,
+ @RequestParam(value = "startNodeList", required = false) String startNodeList,
+ @RequestParam(value = "taskDependType", required = false) TaskDependType taskDependType,
+ @RequestParam(value = "execType", required = false) CommandType execType,
+ @RequestParam(value = "warningType", required = true) WarningType warningType,
+ @RequestParam(value = "warningGroupId", required = false) int warningGroupId,
+ @RequestParam(value = "receivers", required = false) String receivers,
+ @RequestParam(value = "receiversCc", required = false) String receiversCc,
+ @RequestParam(value = "runMode", required = false) RunMode runMode,
+ @RequestParam(value = "processInstancePriority", required = false) Priority processInstancePriority,
+ @RequestParam(value = "workerGroupId", required = false, defaultValue = "-1") int workerGroupId,
+ @RequestParam(value = "timeout", required = false) Integer timeout) {
+ try {
+ logger.info("login user {}, start process instance, project name: {}, process definition id: {}, schedule time: {}, "
+ + "failure policy: {}, node name: {}, node dep: {}, notify type: {}, "
+ + "notify group id: {},receivers:{},receiversCc:{}, run mode: {},process instance priority:{}, workerGroupId: {}, timeout: {}",
+ loginUser.getUserName(), projectName, processDefinitionId, scheduleTime,
+ failureStrategy, startNodeList, taskDependType, warningType, warningGroupId,receivers,receiversCc,runMode,processInstancePriority,
+ workerGroupId, timeout);
+
+ if (timeout == null) {
+ timeout = org.apache.dolphinscheduler.common.Constants.MAX_TASK_TIMEOUT;
+ }
+
+ Map result = execService.execProcessInstance(loginUser, projectName, processDefinitionId, scheduleTime, execType, failureStrategy,
+ startNodeList, taskDependType, warningType,
+ warningGroupId,receivers,receiversCc, runMode,processInstancePriority, workerGroupId, timeout);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(Status.START_PROCESS_INSTANCE_ERROR.getMsg(),e);
+ return error(Status.START_PROCESS_INSTANCE_ERROR.getCode(), Status.START_PROCESS_INSTANCE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * do action to process instance:pause, stop, repeat, recover from pause, recover from stop
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processInstanceId
+ * @return
+ */
+ @ApiOperation(value = "execute", notes= "EXECUTE_ACTION_TO_PROCESS_INSTANCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "executeType", value = "EXECUTE_TYPE", required = true, dataType = "ExecuteType")
+ })
+ @PostMapping(value = "/execute")
+ @ResponseStatus(HttpStatus.OK)
+ public Result execute(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("processInstanceId") Integer processInstanceId,
+ @RequestParam("executeType") ExecuteType executeType
+ ) {
+ try {
+ logger.info("execute command, login user: {}, project:{}, process instance id:{}, execute type:{}",
+ loginUser.getUserName(), projectName, processInstanceId, executeType.toString());
+ Map result = execService.execute(loginUser, projectName, processInstanceId, executeType);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(Status.EXECUTE_PROCESS_INSTANCE_ERROR.getMsg(),e);
+ return error(Status.EXECUTE_PROCESS_INSTANCE_ERROR.getCode(), Status.EXECUTE_PROCESS_INSTANCE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * check process definition and all of the son process definitions is on line.
+ *
+ * @param loginUser
+ * @param processDefinitionId
+ * @return
+ */
+ @ApiOperation(value = "startCheckProcessDefinition", notes= "START_CHECK_PROCESS_DEFINITION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100")
+ })
+ @PostMapping(value = "/start-check")
+ @ResponseStatus(HttpStatus.OK)
+ public Result startCheckProcessDefinition(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "processDefinitionId") int processDefinitionId) {
+ logger.info("login user {}, check process definition", loginUser.getUserName(), processDefinitionId);
+ try {
+ Map result = execService.startCheckByProcessDefinedId(processDefinitionId);
+ return returnDataList(result);
+
+ } catch (Exception e) {
+ logger.error(Status.CHECK_PROCESS_DEFINITION_ERROR.getMsg(),e);
+ return error(Status.CHECK_PROCESS_DEFINITION_ERROR.getCode(), Status.CHECK_PROCESS_DEFINITION_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query recipients and copyers by process definition ID
+ *
+ * @param loginUser
+ * @param processDefinitionId
+ * @return
+ */
+ @ApiIgnore
+ @ApiOperation(value = "getReceiverCc", notes= "GET_RECEIVER_CC_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", required = true, dataType = "Int", example = "100")
+
+ })
+ @GetMapping(value = "/get-receiver-cc")
+ @ResponseStatus(HttpStatus.OK)
+ public Result getReceiverCc(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "processDefinitionId",required = false) Integer processDefinitionId,
+ @RequestParam(value = "processInstanceId",required = false) Integer processInstanceId) {
+ logger.info("login user {}, get process definition receiver and cc", loginUser.getUserName());
+ try {
+ Map result = execService.getReceiverCc(processDefinitionId,processInstanceId);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(Status.QUERY_RECIPIENTS_AND_COPYERS_BY_PROCESS_DEFINITION_ERROR.getMsg(),e);
+ return error(Status.QUERY_RECIPIENTS_AND_COPYERS_BY_PROCESS_DEFINITION_ERROR.getCode(), Status.QUERY_RECIPIENTS_AND_COPYERS_BY_PROCESS_DEFINITION_ERROR.getMsg());
+ }
+ }
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
new file mode 100644
index 0000000000..e04101ad7f
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.service.LoggerService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+
+/**
+ * log controller
+ */
+@Api(tags = "LOGGER_TAG", position = 13)
+@RestController
+@RequestMapping("/log")
+public class LoggerController extends BaseController {
+
+ private static final Logger logger = LoggerFactory.getLogger(LoggerController.class);
+
+
+ @Autowired
+ private LoggerService loggerService;
+
+ /**
+ * query task log
+ */
+ @ApiOperation(value = "queryLog", notes= "QUERY_TASK_INSTANCE_LOG_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "taskInstId", value = "TASK_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "skipLineNum", value = "SKIP_LINE_NUM", dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "limit", value = "LIMIT", dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/detail")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryLog(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "taskInstId") int taskInstanceId,
+ @RequestParam(value = "skipLineNum") int skipNum,
+ @RequestParam(value = "limit") int limit) {
+ try {
+
+ logger.info(
+ "login user {}, view {} task instance log ,skipLineNum {} , limit {}", loginUser.getUserName(), taskInstanceId, skipNum, limit);
+ return loggerService.queryLog(taskInstanceId, skipNum, limit);
+ } catch (Exception e) {
+ logger.error(Status.QUERY_TASK_INSTANCE_LOG_ERROR.getMsg(), e);
+ return error(Status.QUERY_TASK_INSTANCE_LOG_ERROR.getCode(), Status.QUERY_TASK_INSTANCE_LOG_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * download log file
+ *
+ * @param loginUser
+ * @param taskInstanceId
+ */
+ @ApiOperation(value = "downloadTaskLog", notes= "DOWNLOAD_TASK_INSTANCE_LOG_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "taskInstId", value = "TASK_ID",dataType = "Int", example = "100")
+ })
+ @GetMapping(value = "/download-log")
+ @ResponseBody
+ public ResponseEntity downloadTaskLog(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "taskInstId") int taskInstanceId) {
+ try {
+ byte[] logBytes = loggerService.getLogBytes(taskInstanceId);
+ return ResponseEntity
+ .ok()
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + System.currentTimeMillis() + ".queryLog" + "\"")
+ .body(logBytes);
+ } catch (Exception e) {
+ logger.error(Status.DOWNLOAD_TASK_INSTANCE_LOG_FILE_ERROR.getMsg(), e);
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Status.DOWNLOAD_TASK_INSTANCE_LOG_FILE_ERROR.getMsg());
+ }
+ }
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoginController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoginController.java
new file mode 100644
index 0000000000..81911c62a1
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoginController.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.SessionService;
+import org.apache.dolphinscheduler.api.service.UsersService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.*;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+
+/**
+ * user login controller
+ *
+ * swagger bootstrap ui docs refer : https://doc.xiaominfo.com/guide/enh-func.html
+ */
+@Api(tags = "LOGIN_TAG", position = 1)
+@RestController
+@RequestMapping("")
+public class LoginController extends BaseController {
+
+ private static final Logger logger = LoggerFactory.getLogger(LoginController.class);
+
+
+ @Autowired
+ private SessionService sessionService;
+
+ @Autowired
+ private UsersService userService;
+
+
+ /**
+ * login
+ *
+ * @param userName
+ * @param userPassword
+ * @param request
+ * @param response
+ * @return
+ */
+ @ApiOperation(value = "login", notes= "LOGIN_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userName", value = "USER_NAME", required = true, dataType = "String"),
+ @ApiImplicitParam(name = "userPassword", value = "USER_PASSWORD", required = true, dataType ="String")
+ })
+ @PostMapping(value = "/login")
+ public Result login(@RequestParam(value = "userName") String userName,
+ @RequestParam(value = "userPassword") String userPassword,
+ HttpServletRequest request,
+ HttpServletResponse response) {
+
+ try {
+ logger.info("login user name: {} ", userName);
+
+ //user name check
+ if (StringUtils.isEmpty(userName)) {
+ return error(Status.USER_NAME_NULL.getCode(),
+ Status.USER_NAME_NULL.getMsg());
+ }
+
+ // user ip check
+ String ip = getClientIpAddress(request);
+ if (StringUtils.isEmpty(ip)) {
+ return error(IP_IS_EMPTY.getCode(), IP_IS_EMPTY.getMsg());
+ }
+
+ // verify username and password
+ User user = userService.queryUser(userName, userPassword);
+
+ if (user == null) {
+ return error(Status.USER_NAME_PASSWD_ERROR.getCode(),Status.USER_NAME_PASSWD_ERROR.getMsg()
+ );
+ }
+
+ // create session
+ String sessionId = sessionService.createSession(user, ip);
+
+ if (sessionId == null) {
+ return error(Status.LOGIN_SESSION_FAILED.getCode(),
+ Status.LOGIN_SESSION_FAILED.getMsg()
+ );
+ }
+
+ response.setStatus(HttpStatus.SC_OK);
+ response.addCookie(new Cookie(Constants.SESSION_ID, sessionId));
+
+ logger.info("sessionId : {}" , sessionId);
+ return success(LOGIN_SUCCESS.getMsg(), sessionId);
+ } catch (Exception e) {
+ logger.error(USER_LOGIN_FAILURE.getMsg(),e);
+ return error(USER_LOGIN_FAILURE.getCode(), USER_LOGIN_FAILURE.getMsg());
+ }
+ }
+
+ /**
+ * sign out
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "signOut", notes = "SIGNOUT_NOTES")
+ @PostMapping(value = "/signOut")
+ public Result signOut(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ HttpServletRequest request) {
+
+ try {
+ logger.info("login user:{} sign out", loginUser.getUserName());
+ String ip = getClientIpAddress(request);
+ sessionService.signOut(ip, loginUser);
+ //clear session
+ request.removeAttribute(Constants.SESSION_USER);
+ return success();
+ } catch (Exception e) {
+ logger.error(SIGN_OUT_ERROR.getMsg(),e);
+ return error(SIGN_OUT_ERROR.getCode(), SIGN_OUT_ERROR.getMsg());
+ }
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/MonitorController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/MonitorController.java
new file mode 100644
index 0000000000..396675b97d
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/MonitorController.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.service.MonitorService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+/**
+ * monitor controller
+ */
+@Api(tags = "MONITOR_TAG", position = 1)
+@RestController
+@RequestMapping("/monitor")
+public class MonitorController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(MonitorController.class);
+
+ @Autowired
+ private MonitorService monitorService;
+
+ /**
+ * master list
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "listMaster", notes= "MASTER_LIST_NOTES")
+ @GetMapping(value = "/master/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result listMaster(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
+ logger.info("login user: {}, query all master", loginUser.getUserName());
+ try{
+ logger.info("list master, user:{}", loginUser.getUserName());
+ Map result = monitorService.queryMaster(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(LIST_MASTERS_ERROR.getMsg(),e);
+ return error(LIST_MASTERS_ERROR.getCode(),
+ LIST_MASTERS_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * worker list
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "listWorker", notes= "WORKER_LIST_NOTES")
+ @GetMapping(value = "/worker/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result listWorker(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
+ logger.info("login user: {}, query all workers", loginUser.getUserName());
+ try{
+ Map result = monitorService.queryWorker(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(LIST_WORKERS_ERROR.getMsg(),e);
+ return error(LIST_WORKERS_ERROR.getCode(),
+ LIST_WORKERS_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query database state
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryDatabaseState", notes= "QUERY_DATABASE_STATE_NOTES")
+ @GetMapping(value = "/database")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryDatabaseState(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
+ logger.info("login user: {}, query database state", loginUser.getUserName());
+ try{
+
+ Map result = monitorService.queryDatabaseState(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_DATABASE_STATE_ERROR.getMsg(),e);
+ return error(QUERY_DATABASE_STATE_ERROR.getCode(),
+ QUERY_DATABASE_STATE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query zookeeper state
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryZookeeperState", notes= "QUERY_ZOOKEEPER_STATE_NOTES")
+ @GetMapping(value = "/zookeeper/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryZookeeperState(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
+ logger.info("login user: {}, query zookeeper state", loginUser.getUserName());
+ try{
+ Map result = monitorService.queryZookeeperState(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_ZOOKEEPER_STATE_ERROR.getMsg(),e);
+ return error(QUERY_ZOOKEEPER_STATE_ERROR.getCode(),
+ QUERY_ZOOKEEPER_STATE_ERROR.getMsg());
+ }
+ }
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java
new file mode 100644
index 0000000000..5f3ab86d02
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java
@@ -0,0 +1,491 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.ProcessDefinitionService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+
+/**
+ * process definition controller
+ */
+@Api(tags = "PROCESS_DEFINITION_TAG", position = 2)
+@RestController
+@RequestMapping("projects/{projectName}/process")
+public class ProcessDefinitionController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(ProcessDefinitionController.class);
+
+ @Autowired
+ private ProcessDefinitionService processDefinitionService;
+
+ /**
+ * create process definition
+ *
+ * @param loginUser
+ * @param projectName
+ * @param name
+ * @param json process definition json
+ * @param desc
+ * @return
+ */
+ @ApiOperation(value = "save", notes= "CREATE_PROCESS_DEFINITION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name", value = "PROCESS_DEFINITION_NAME", required = true, type = "String"),
+ @ApiImplicitParam(name = "processDefinitionJson", value = "PROCESS_DEFINITION_JSON", required = true, type ="String"),
+ @ApiImplicitParam(name = "locations", value = "PROCESS_DEFINITION_LOCATIONS", required = true, type ="String"),
+ @ApiImplicitParam(name = "connects", value = "PROCESS_DEFINITION_CONNECTS", required = true, type ="String"),
+ @ApiImplicitParam(name = "desc", value = "PROCESS_DEFINITION_DESC", required = false, type ="String"),
+ })
+ @PostMapping(value = "/save")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createProcessDefinition(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam(value = "name", required = true) String name,
+ @RequestParam(value = "processDefinitionJson", required = true) String json,
+ @RequestParam(value = "locations", required = true) String locations,
+ @RequestParam(value = "connects", required = true) String connects,
+ @RequestParam(value = "desc", required = false) String desc) {
+
+ try {
+ logger.info("login user {}, create process definition, project name: {}, process definition name: {}, " +
+ "process_definition_json: {}, desc: {} locations:{}, connects:{}",
+ loginUser.getUserName(), projectName, name, json, desc, locations, connects);
+ Map result = processDefinitionService.createProcessDefinition(loginUser, projectName, name, json,
+ desc, locations, connects);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(Status.CREATE_PROCESS_DEFINITION.getMsg(), e);
+ return error(Status.CREATE_PROCESS_DEFINITION.getCode(), Status.CREATE_PROCESS_DEFINITION.getMsg());
+ }
+ }
+
+ /**
+ * verify process definition name unique
+ *
+ * @param loginUser
+ * @param projectName
+ * @param name
+ * @return
+ */
+ @ApiOperation(value = "verify-name", notes = "VERIFY_PROCCESS_DEFINITION_NAME_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name", value = "PROCESS_DEFINITION_NAME", required = true, type = "String")
+ })
+ @GetMapping(value = "/verify-name")
+ @ResponseStatus(HttpStatus.OK)
+ public Result verifyProccessDefinitionName(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName,
+ @RequestParam(value = "name", required = true) String name){
+ try {
+ logger.info("verify process definition name unique, user:{}, project name:{}, process definition name:{}",
+ loginUser.getUserName(), projectName, name);
+ Map result = processDefinitionService.verifyProccessDefinitionName(loginUser, projectName, name);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.VERIFY_PROCESS_DEFINITION_NAME_UNIQUE_ERROR.getMsg(),e);
+ return error(Status.VERIFY_PROCESS_DEFINITION_NAME_UNIQUE_ERROR.getCode(), Status.VERIFY_PROCESS_DEFINITION_NAME_UNIQUE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * update process definition
+ *
+ * @param loginUser
+ * @param projectName
+ * @param name
+ * @param id
+ * @param processDefinitionJson
+ * @param desc
+ * @return
+ */
+ @ApiOperation(value = "updateProccessDefinition", notes= "UPDATE_PROCCESS_DEFINITION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name", value = "PROCESS_DEFINITION_NAME", required = true, type = "String"),
+ @ApiImplicitParam(name = "id", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "processDefinitionJson", value = "PROCESS_DEFINITION_JSON", required = true, type ="String"),
+ @ApiImplicitParam(name = "locations", value = "PROCESS_DEFINITION_LOCATIONS", required = true, type ="String"),
+ @ApiImplicitParam(name = "connects", value = "PROCESS_DEFINITION_CONNECTS", required = true, type ="String"),
+ @ApiImplicitParam(name = "desc", value = "PROCESS_DEFINITION_DESC", required = false, type ="String"),
+ })
+ @PostMapping(value = "/update")
+ @ResponseStatus(HttpStatus.OK)
+ public Result updateProccessDefinition(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName,
+ @RequestParam(value = "name", required = true) String name,
+ @RequestParam(value = "id", required = true) int id,
+ @RequestParam(value = "processDefinitionJson", required = true) String processDefinitionJson,
+ @RequestParam(value = "locations", required = false) String locations,
+ @RequestParam(value = "connects", required = false) String connects,
+ @RequestParam(value = "desc", required = false) String desc) {
+
+ try {
+ logger.info("login user {}, update process define, project name: {}, process define name: {}, " +
+ "process_definition_json: {}, desc: {}, locations:{}, connects:{}",
+ loginUser.getUserName(), projectName, name, processDefinitionJson,desc, locations, connects);
+ Map result = processDefinitionService.updateProcessDefinition(loginUser, projectName, id, name,
+ processDefinitionJson, desc, locations, connects);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.UPDATE_PROCESS_DEFINITION_ERROR.getMsg(),e);
+ return error(Status.UPDATE_PROCESS_DEFINITION_ERROR.getCode(), Status.UPDATE_PROCESS_DEFINITION_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * release process definition
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processId
+ * @param releaseState
+ * @return
+ */
+ @ApiOperation(value = "releaseProccessDefinition", notes= "RELEASE_PROCCESS_DEFINITION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name", value = "PROCESS_DEFINITION_NAME", required = true, type = "String"),
+ @ApiImplicitParam(name = "processId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "releaseState", value = "PROCESS_DEFINITION_CONNECTS", required = true, dataType = "Int", example = "100"),
+ })
+ @PostMapping(value = "/release")
+ @ResponseStatus(HttpStatus.OK)
+ public Result releaseProccessDefinition(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName,
+ @RequestParam(value = "processId", required = true) int processId,
+ @RequestParam(value = "releaseState", required = true) int releaseState) {
+
+ try {
+ logger.info("login user {}, release process definition, project name: {}, release state: {}",
+ loginUser.getUserName(), projectName, releaseState);
+ Map result = processDefinitionService.releaseProcessDefinition(loginUser, projectName, processId, releaseState);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.RELEASE_PROCESS_DEFINITION_ERROR.getMsg(),e);
+ return error(Status.RELEASE_PROCESS_DEFINITION_ERROR.getCode(), Status.RELEASE_PROCESS_DEFINITION_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * query datail of process definition
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processId
+ * @return
+ */
+ @ApiOperation(value = "queryProccessDefinitionById", notes= "QUERY_PROCCESS_DEFINITION_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/select-by-id")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryProccessDefinitionById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName,
+ @RequestParam("processId") Integer processId
+ ){
+ try{
+ logger.info("query datail of process definition, login user:{}, project name:{}, process definition id:{}",
+ loginUser.getUserName(), projectName, processId);
+ Map result = processDefinitionService.queryProccessDefinitionById(loginUser, projectName, processId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_DATAIL_OF_PROCESS_DEFINITION_ERROR.getMsg(),e);
+ return error(Status.QUERY_DATAIL_OF_PROCESS_DEFINITION_ERROR.getCode(), Status.QUERY_DATAIL_OF_PROCESS_DEFINITION_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * query proccess definition list
+ *
+ * @param loginUser
+ * @param projectName
+ * @return
+ */
+ @ApiOperation(value = "queryProccessDefinitionList", notes= "QUERY_PROCCESS_DEFINITION_LIST_NOTES")
+ @GetMapping(value="/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryProccessDefinitionList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName
+ ){
+ try{
+ logger.info("query proccess definition list, login user:{}, project name:{}",
+ loginUser.getUserName(), projectName);
+ Map result = processDefinitionService.queryProccessDefinitionList(loginUser, projectName);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_PROCCESS_DEFINITION_LIST.getMsg(),e);
+ return error(Status.QUERY_PROCCESS_DEFINITION_LIST.getCode(), Status.QUERY_PROCCESS_DEFINITION_LIST.getMsg());
+ }
+ }
+
+ /**
+ * query proccess definition list paging
+ * @param loginUser
+ * @param projectName
+ * @param pageNo
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryProcessDefinitionListPaging", notes= "QUERY_PROCCESS_DEFINITION_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", required = false, type = "String"),
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = false, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", required = true, dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryProcessDefinitionListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam(value = "userId", required = false, defaultValue = "0") Integer userId,
+ @RequestParam("pageSize") Integer pageSize){
+ try{
+ logger.info("query proccess definition list paging, login user:{}, project name:{}", loginUser.getUserName(), projectName);
+ Map result = checkPageParams(pageNo, pageSize);
+ if(result.get(Constants.STATUS) != Status.SUCCESS){
+ return returnDataListPaging(result);
+ }
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ result = processDefinitionService.queryProcessDefinitionListPaging(loginUser, projectName, searchVal, pageNo, pageSize, userId);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_PROCCESS_DEFINITION_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_PROCCESS_DEFINITION_LIST_PAGING_ERROR.getCode(), Status.QUERY_PROCCESS_DEFINITION_LIST_PAGING_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * encapsulation treeview structure
+ *
+ * @param loginUser
+ * @param projectName
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "viewTree", notes= "VIEW_TREE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "limit", value = "LIMIT", required = true, dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/view-tree")
+ @ResponseStatus(HttpStatus.OK)
+ public Result viewTree(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName,
+ @RequestParam("processId") Integer id,
+ @RequestParam("limit") Integer limit){
+ try{
+ Map result = processDefinitionService.viewTree(id, limit);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.ENCAPSULATION_TREEVIEW_STRUCTURE_ERROR.getMsg(),e);
+ return error(Status.ENCAPSULATION_TREEVIEW_STRUCTURE_ERROR.getCode(), Status.ENCAPSULATION_TREEVIEW_STRUCTURE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ *
+ * get tasks list by process definition id
+ *
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processDefinitionId
+ * @return
+ */
+ @ApiOperation(value = "getNodeListByDefinitionId", notes= "GET_NODE_LIST_BY_DEFINITION_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100")
+ })
+ @GetMapping(value="gen-task-list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result getNodeListByDefinitionId(
+ @ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName,
+ @RequestParam("processDefinitionId") Integer processDefinitionId){
+ try {
+ logger.info("query task node name list by definitionId, login user:{}, project name:{}, id : {}",
+ loginUser.getUserName(), projectName, processDefinitionId);
+ Map result = processDefinitionService.getTaskNodeListByDefinitionId(processDefinitionId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR.getMsg(), e);
+ return error(Status.GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR.getCode(), Status.GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ *
+ * get tasks list by process definition id
+ *
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processDefinitionIdList
+ * @return
+ */
+ @ApiOperation(value = "getNodeListByDefinitionIdList", notes= "GET_NODE_LIST_BY_DEFINITION_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionIdList", value = "PROCESS_DEFINITION_ID_LIST", required = true, type = "String")
+ })
+ @GetMapping(value="get-task-list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result getNodeListByDefinitionIdList(
+ @ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME",required = true) @PathVariable String projectName,
+ @RequestParam("processDefinitionIdList") String processDefinitionIdList){
+
+ try {
+ logger.info("query task node name list by definitionId list, login user:{}, project name:{}, id list: {}",
+ loginUser.getUserName(), projectName, processDefinitionIdList);
+ Map result = processDefinitionService.getTaskNodeListByDefinitionIdList(processDefinitionIdList);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR.getMsg(), e);
+ return error(Status.GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR.getCode(), Status.GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete process definition by id
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processDefinitionId
+ * @return
+ */
+ @ApiOperation(value = "deleteProcessDefinitionById", notes= "DELETE_PROCESS_DEFINITION_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result deleteProcessDefinitionById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("processDefinitionId") Integer processDefinitionId
+ ){
+ try{
+ logger.info("delete process definition by id, login user:{}, project name:{}, process definition id:{}",
+ loginUser.getUserName(), projectName, processDefinitionId);
+ Map result = processDefinitionService.deleteProcessDefinitionById(loginUser, projectName, processDefinitionId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.DELETE_PROCESS_DEFINE_BY_ID_ERROR.getMsg(),e);
+ return error(Status.DELETE_PROCESS_DEFINE_BY_ID_ERROR.getCode(), Status.DELETE_PROCESS_DEFINE_BY_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * batch delete process definition by ids
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processDefinitionIds
+ * @return
+ */
+ @ApiOperation(value = "batchDeleteProcessDefinitionByIds", notes= "BATCH_DELETE_PROCESS_DEFINITION_BY_IDS_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionIds", value = "PROCESS_DEFINITION_IDS", type = "String")
+ })
+ @GetMapping(value="/batch-delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result batchDeleteProcessDefinitionByIds(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("processDefinitionIds") String processDefinitionIds
+ ){
+ try{
+ logger.info("delete process definition by ids, login user:{}, project name:{}, process definition ids:{}",
+ loginUser.getUserName(), projectName, processDefinitionIds);
+ Map result = processDefinitionService.batchDeleteProcessDefinitionByIds(loginUser, projectName, processDefinitionIds);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.BATCH_DELETE_PROCESS_DEFINE_BY_IDS_ERROR.getMsg(),e);
+ return error(Status.BATCH_DELETE_PROCESS_DEFINE_BY_IDS_ERROR.getCode(), Status.BATCH_DELETE_PROCESS_DEFINE_BY_IDS_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * export process definition by id
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processDefinitionId
+ * @return
+ */
+ @ApiOperation(value = "exportProcessDefinitionById", notes= "EXPORT_PROCCESS_DEFINITION_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/export")
+ @ResponseBody
+ public void exportProcessDefinitionById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @PathVariable String projectName,
+ @RequestParam("processDefinitionId") Integer processDefinitionId,
+ HttpServletResponse response){
+ try{
+ logger.info("export process definition by id, login user:{}, project name:{}, process definition id:{}",
+ loginUser.getUserName(), projectName, processDefinitionId);
+ processDefinitionService.exportProcessDefinitionById(loginUser, projectName, processDefinitionId,response);
+ }catch (Exception e){
+ logger.error(Status.EXPORT_PROCESS_DEFINE_BY_ID_ERROR.getMsg(),e);
+ }
+ }
+
+
+
+ /**
+ * query proccess definition all by project id
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryProccessDefinitionAllByProjectId", notes= "QUERY_PROCCESS_DEFINITION_All_BY_PROJECT_ID_NOTES")
+ @GetMapping(value="/queryProccessDefinitionAllByProjectId")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryProccessDefinitionAllByProjectId(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("projectId") Integer projectId){
+ try{
+ logger.info("query proccess definition list, login user:{}, project id:{}",
+ loginUser.getUserName(),projectId);
+ Map result = processDefinitionService.queryProccessDefinitionAllByProjectId(projectId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_PROCCESS_DEFINITION_LIST.getMsg(),e);
+ return error(Status.QUERY_PROCCESS_DEFINITION_LIST.getCode(), Status.QUERY_PROCCESS_DEFINITION_LIST.getMsg());
+ }
+ }
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessInstanceController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessInstanceController.java
new file mode 100644
index 0000000000..04233985d8
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessInstanceController.java
@@ -0,0 +1,367 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.ProcessInstanceService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.enums.ExecutionStatus;
+import org.apache.dolphinscheduler.common.enums.Flag;
+import org.apache.dolphinscheduler.common.queue.ITaskQueue;
+import org.apache.dolphinscheduler.common.queue.TaskQueueFactory;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+
+/**
+ * process instance controller
+ */
+@Api(tags = "PROCESS_INSTANCE_TAG", position = 10)
+@RestController
+@RequestMapping("projects/{projectName}/instance")
+public class ProcessInstanceController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(ProcessInstanceController.class);
+
+
+ @Autowired
+ ProcessInstanceService processInstanceService;
+
+ /**
+ * query process instance list paging
+ *
+ * @param loginUser
+ * @param projectName
+ * @param pageNo
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryProcessInstanceList", notes= "QUERY_PROCESS_INSTANCE_LIST_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", type ="String"),
+ @ApiImplicitParam(name = "stateType", value = "EXECUTION_STATUS", type ="ExecutionStatus"),
+ @ApiImplicitParam(name = "host", value = "HOST", type ="String"),
+ @ApiImplicitParam(name = "startDate", value = "START_DATE", type ="String"),
+ @ApiImplicitParam(name = "endDate", value = "END_DATE", type ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryProcessInstanceList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam(value = "processDefinitionId", required = false, defaultValue = "0") Integer processDefinitionId,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam(value = "stateType", required = false) ExecutionStatus stateType,
+ @RequestParam(value = "host", required = false) String host,
+ @RequestParam(value = "startDate", required = false) String startTime,
+ @RequestParam(value = "endDate", required = false) String endTime,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam("pageSize") Integer pageSize){
+ try{
+ logger.info("query all process instance list, login user:{},project name:{}, define id:{}," +
+ "search value:{},state type:{},host:{},start time:{}, end time:{},page number:{}, page size:{}",
+ loginUser.getUserName(), projectName, processDefinitionId, searchVal, stateType,host,
+ startTime, endTime, pageNo, pageSize);
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ Map result = processInstanceService.queryProcessInstanceList(
+ loginUser, projectName, processDefinitionId, startTime, endTime, searchVal, stateType, host, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(QUERY_PROCESS_INSTANCE_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_PROCESS_INSTANCE_LIST_PAGING_ERROR.getCode(), Status.QUERY_PROCESS_INSTANCE_LIST_PAGING_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query task list by process instance id
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processInstanceId
+ * @return
+ */
+ @ApiOperation(value = "queryTaskListByProcessId", notes= "QUERY_TASK_LIST_BY_PROCESS_INSTANCE_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/task-list-by-process-id")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryTaskListByProcessId(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("processInstanceId") Integer processInstanceId
+ ) {
+ try{
+ logger.info("query task instance list by process instance id, login user:{}, project name:{}, process instance id:{}",
+ loginUser.getUserName(), projectName, processInstanceId);
+ Map result = processInstanceService.queryTaskListByProcessId(loginUser, projectName, processInstanceId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_TASK_LIST_BY_PROCESS_INSTANCE_ID_ERROR.getMsg(),e);
+ return error(QUERY_TASK_LIST_BY_PROCESS_INSTANCE_ID_ERROR.getCode(), QUERY_TASK_LIST_BY_PROCESS_INSTANCE_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * update process instance
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processInstanceJson
+ * @param processInstanceId
+ * @param scheduleTime
+ * @param syncDefine
+ * @param flag
+ * @return
+ */
+ @ApiOperation(value = "updateProcessInstance", notes= "UPDATE_PROCESS_INSTANCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processInstanceJson", value = "PROCESS_INSTANCE_JSON", type = "String"),
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "scheduleTime", value = "SCHEDULE_TIME", type = "String"),
+ @ApiImplicitParam(name = "syncDefine", value = "SYNC_DEFINE", type = "Boolean"),
+ @ApiImplicitParam(name = "locations", value = "PROCESS_INSTANCE_LOCATIONS", type = "String"),
+ @ApiImplicitParam(name = "connects", value = "PROCESS_INSTANCE_CONNECTS", type = "String"),
+ @ApiImplicitParam(name = "flag", value = "RECOVERY_PROCESS_INSTANCE_FLAG", type = "Flag"),
+ })
+ @PostMapping(value="/update")
+ @ResponseStatus(HttpStatus.OK)
+ public Result updateProcessInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam( value = "processInstanceJson", required = false) String processInstanceJson,
+ @RequestParam( value = "processInstanceId") Integer processInstanceId,
+ @RequestParam( value = "scheduleTime", required = false) String scheduleTime,
+ @RequestParam( value = "syncDefine", required = true) Boolean syncDefine,
+ @RequestParam(value = "locations", required = false) String locations,
+ @RequestParam(value = "connects", required = false) String connects,
+ @RequestParam( value = "flag", required = false) Flag flag
+ ){
+ try{
+ logger.info("updateProcessInstance process instance, login user:{}, project name:{}, process instance json:{}," +
+ "process instance id:{}, schedule time:{}, sync define:{}, flag:{}, locations:{}, connects:{}",
+ loginUser.getUserName(), projectName, processInstanceJson, processInstanceId, scheduleTime,
+ syncDefine, flag, locations, connects);
+ Map result = processInstanceService.updateProcessInstance(loginUser, projectName,
+ processInstanceId, processInstanceJson, scheduleTime, syncDefine, flag, locations, connects);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(UPDATE_PROCESS_INSTANCE_ERROR.getMsg(),e);
+ return error(Status.UPDATE_PROCESS_INSTANCE_ERROR.getCode(), Status.UPDATE_PROCESS_INSTANCE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query process instance by id
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processInstanceId
+ * @return
+ */
+ @ApiOperation(value = "queryProcessInstanceById", notes= "QUERY_PROCESS_INSTANCE_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/select-by-id")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryProcessInstanceById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("processInstanceId") Integer processInstanceId
+ ){
+ try{
+ logger.info("query process instance detail by id, login user:{},project name:{}, process instance id:{}",
+ loginUser.getUserName(), projectName, processInstanceId);
+ Map result = processInstanceService.queryProcessInstanceById(loginUser, projectName, processInstanceId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_PROCESS_INSTANCE_BY_ID_ERROR.getMsg(),e);
+ return error(Status.QUERY_PROCESS_INSTANCE_BY_ID_ERROR.getCode(), Status.QUERY_PROCESS_INSTANCE_BY_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete process instance by id, at the same time,
+ * delete task instance and their mapping relation data
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processInstanceId
+ * @return
+ */
+ @ApiOperation(value = "deleteProcessInstanceById", notes= "DELETE_PROCESS_INSTANCE_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result deleteProcessInstanceById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("processInstanceId") Integer processInstanceId
+ ){
+ try{
+ logger.info("delete process instance by id, login user:{}, project name:{}, process instance id:{}",
+ loginUser.getUserName(), projectName, processInstanceId);
+ // task queue
+ ITaskQueue tasksQueue = TaskQueueFactory.getTaskQueueInstance();
+ Map result = processInstanceService.deleteProcessInstanceById(loginUser, projectName, processInstanceId,tasksQueue);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(DELETE_PROCESS_INSTANCE_BY_ID_ERROR.getMsg(),e);
+ return error(Status.DELETE_PROCESS_INSTANCE_BY_ID_ERROR.getCode(), Status.DELETE_PROCESS_INSTANCE_BY_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query sub process instance detail info by task id
+ *
+ * @param loginUser
+ * @param projectName
+ * @param taskId
+ * @return
+ */
+ @ApiOperation(value = "querySubProcessInstanceByTaskId", notes= "QUERY_SUBPROCESS_INSTANCE_BY_TASK_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "taskId", value = "TASK_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/select-sub-process")
+ @ResponseStatus(HttpStatus.OK)
+ public Result querySubProcessInstanceByTaskId(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("taskId") Integer taskId){
+ try{
+ Map result = processInstanceService.querySubProcessInstanceByTaskId(loginUser, projectName, taskId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_SUB_PROCESS_INSTANCE_DETAIL_INFO_BY_TASK_ID_ERROR.getMsg(),e);
+ return error(Status.QUERY_SUB_PROCESS_INSTANCE_DETAIL_INFO_BY_TASK_ID_ERROR.getCode(), Status.QUERY_SUB_PROCESS_INSTANCE_DETAIL_INFO_BY_TASK_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query parent process instance detail info by sub process instance id
+ *
+ * @param loginUser
+ * @param projectName
+ * @param subId
+ * @return
+ */
+ @ApiOperation(value = "queryParentInstanceBySubId", notes= "QUERY_PARENT_PROCESS_INSTANCE_BY_SUB_PROCESS_INSTANCE_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "subId", value = "SUB_PROCESS_INSTANCE_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/select-parent-process")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryParentInstanceBySubId(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("subId") Integer subId){
+ try{
+ Map result = processInstanceService.queryParentInstanceBySubId(loginUser, projectName, subId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_PARENT_PROCESS_INSTANCE_DETAIL_INFO_BY_SUB_PROCESS_INSTANCE_ID_ERROR.getMsg(),e);
+ return error(Status.QUERY_PARENT_PROCESS_INSTANCE_DETAIL_INFO_BY_SUB_PROCESS_INSTANCE_ID_ERROR.getCode(), Status.QUERY_PARENT_PROCESS_INSTANCE_DETAIL_INFO_BY_SUB_PROCESS_INSTANCE_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query process instance global variables and local variables
+ *
+ * @param loginUser
+ * @param processInstanceId
+ * @return
+ */
+ @ApiOperation(value = "viewVariables", notes= "QUERY_PROCESS_INSTANCE_GLOBAL_VARIABLES_AND_LOCAL_VARIABLES_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/view-variables")
+ @ResponseStatus(HttpStatus.OK)
+ public Result viewVariables(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser
+ , @RequestParam("processInstanceId") Integer processInstanceId){
+ try{
+ Map result = processInstanceService.viewVariables(processInstanceId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_PROCESS_INSTANCE_ALL_VARIABLES_ERROR.getMsg(),e);
+ return error(Status.QUERY_PROCESS_INSTANCE_ALL_VARIABLES_ERROR.getCode(), Status.QUERY_PROCESS_INSTANCE_ALL_VARIABLES_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * encapsulation gantt structure
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processInstanceId
+ * @return
+ */
+ @ApiOperation(value = "vieGanttTree", notes= "VIEW_GANTT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/view-gantt")
+ @ResponseStatus(HttpStatus.OK)
+ public Result viewTree(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam("processInstanceId") Integer processInstanceId){
+ try{
+ Map result = processInstanceService.viewGantt(processInstanceId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(ENCAPSULATION_PROCESS_INSTANCE_GANTT_STRUCTURE_ERROR.getMsg(),e);
+ return error(Status.ENCAPSULATION_PROCESS_INSTANCE_GANTT_STRUCTURE_ERROR.getCode(),ENCAPSULATION_PROCESS_INSTANCE_GANTT_STRUCTURE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * batch delete process instance by ids, at the same time,
+ * delete task instance and their mapping relation data
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processInstanceIds
+ * @return
+ */
+ @GetMapping(value="/batch-delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result batchDeleteProcessInstanceByIds(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @PathVariable String projectName,
+ @RequestParam("processInstanceIds") String processInstanceIds
+ ){
+ try{
+ logger.info("delete process instance by ids, login user:{}, project name:{}, process instance ids :{}",
+ loginUser.getUserName(), projectName, processInstanceIds);
+ Map result = processInstanceService.batchDeleteProcessInstanceByIds(loginUser, projectName, processInstanceIds);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(BATCH_DELETE_PROCESS_INSTANCE_BY_IDS_ERROR.getMsg(),e);
+ return error(Status.BATCH_DELETE_PROCESS_INSTANCE_BY_IDS_ERROR.getCode(), Status.BATCH_DELETE_PROCESS_INSTANCE_BY_IDS_ERROR.getMsg());
+ }
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java
new file mode 100644
index 0000000000..d9927bbc2b
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java
@@ -0,0 +1,304 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.ProcessDefinitionService;
+import org.apache.dolphinscheduler.api.service.ProjectService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+
+/**
+ * project controller
+ */
+@Api(tags = "PROJECT_TAG", position = 1)
+@RestController
+@RequestMapping("projects")
+public class ProjectController extends BaseController {
+
+ private static final Logger logger = LoggerFactory.getLogger(ProjectController.class);
+
+ @Autowired
+ private ProjectService projectService;
+
+ @Autowired
+ private ProcessDefinitionService processDefinitionService;
+
+ /**
+ * create project
+ *
+ * @param loginUser
+ * @param projectName
+ * @param desc
+ * @return returns an error if it exists
+ */
+ @ApiOperation(value = "createProject", notes= "CREATE_PROJECT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "projectName", value = "PROJECT_NAME", dataType ="String"),
+ @ApiImplicitParam(name = "desc", value = "PROJECT_DESC", dataType = "String")
+ })
+ @PostMapping(value = "/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createProject(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("projectName") String projectName,
+ @RequestParam(value = "desc", required = false) String desc) {
+
+ try {
+ logger.info("login user {}, create project name: {}, desc: {}", loginUser.getUserName(), projectName, desc);
+ Map result = projectService.createProject(loginUser, projectName, desc);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(CREATE_PROJECT_ERROR.getMsg(), e);
+ return error(CREATE_PROJECT_ERROR.getCode(), CREATE_PROJECT_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * updateProcessInstance project
+ *
+ * @param loginUser
+ * @param projectId
+ * @param projectName
+ * @param desc
+ * @return
+ */
+ @ApiOperation(value = "updateProject", notes= "UPDATE_PROJECT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "projectId", value = "PROJECT_ID", dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "projectName",value = "PROJECT_NAME",dataType = "String"),
+ @ApiImplicitParam(name = "desc", value = "PROJECT_DESC", dataType = "String")
+ })
+ @PostMapping(value = "/update")
+ @ResponseStatus(HttpStatus.OK)
+ public Result updateProject(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("projectId") Integer projectId,
+ @RequestParam("projectName") String projectName,
+ @RequestParam(value = "desc", required = false) String desc) {
+ try {
+ logger.info("login user {} , updateProcessInstance project name: {}, desc: {}", loginUser.getUserName(), projectName, desc);
+ Map result = projectService.update(loginUser, projectId, projectName, desc);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(UPDATE_PROJECT_ERROR.getMsg(), e);
+ return error(UPDATE_PROJECT_ERROR.getCode(), UPDATE_PROJECT_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query project details by id
+ *
+ * @param loginUser
+ * @param projectId
+ * @return
+ */
+ @ApiOperation(value = "queryProjectById", notes= "QUERY_PROJECT_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "projectId", value = "PROJECT_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/query-by-id")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryProjectById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("projectId") Integer projectId) {
+ logger.info("login user {}, query project by id: {}", loginUser.getUserName(), projectId);
+
+ try {
+ Map result = projectService.queryById(projectId);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(QUERY_PROJECT_DETAILS_BY_ID_ERROR.getMsg(), e);
+ return error(QUERY_PROJECT_DETAILS_BY_ID_ERROR.getCode(), QUERY_PROJECT_DETAILS_BY_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query project list paging
+ *
+ * @param loginUser
+ * @param searchVal
+ * @param pageSize
+ * @param pageNo
+ * @return
+ */
+ @ApiOperation(value = "queryProjectListPaging", notes= "QUERY_PROJECT_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", dataType ="String"),
+ @ApiImplicitParam(name = "projectId", value = "PAGE_SIZE", dataType ="Int", example = "20"),
+ @ApiImplicitParam(name = "projectId", value = "PAGE_NO", dataType ="Int", example = "1")
+ })
+ @GetMapping(value = "/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryProjectListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize,
+ @RequestParam("pageNo") Integer pageNo
+ ) {
+
+ try {
+ logger.info("login user {}, query project list paging", loginUser.getUserName());
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ Map result = projectService.queryProjectListPaging(loginUser, pageSize, pageNo, searchVal);
+ return returnDataListPaging(result);
+ } catch (Exception e) {
+ logger.error(LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR.getMsg(), e);
+ return error(Status.LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR.getCode(), Status.LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete project by id
+ *
+ * @param loginUser
+ * @param projectId
+ * @return
+ */
+ @ApiOperation(value = "deleteProjectById", notes= "DELETE_PROJECT_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "projectId", value = "PROJECT_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result deleteProject(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("projectId") Integer projectId
+ ) {
+
+ try {
+ logger.info("login user {}, delete project: {}.", loginUser.getUserName(), projectId);
+ Map result = projectService.deleteProject(loginUser, projectId);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(DELETE_PROJECT_ERROR.getMsg(), e);
+ return error(DELETE_PROJECT_ERROR.getCode(), DELETE_PROJECT_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query unauthorized project
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "queryUnauthorizedProject", notes= "QUERY_UNAUTHORIZED_PROJECT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/unauth-project")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryUnauthorizedProject(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ try {
+ logger.info("login user {}, query unauthorized project by user id: {}.", loginUser.getUserName(), userId);
+ Map result = projectService.queryUnauthorizedProject(loginUser, userId);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(QUERY_UNAUTHORIZED_PROJECT_ERROR.getMsg(), e);
+ return error(QUERY_UNAUTHORIZED_PROJECT_ERROR.getCode(), QUERY_UNAUTHORIZED_PROJECT_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * query authorized project
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "queryAuthorizedProject", notes= "QUERY_AUTHORIZED_PROJECT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/authed-project")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryAuthorizedProject(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ try {
+ logger.info("login user {}, query authorized project by user id: {}.", loginUser.getUserName(), userId);
+ Map result = projectService.queryAuthorizedProject(loginUser, userId);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(QUERY_AUTHORIZED_PROJECT.getMsg(), e);
+ return error(QUERY_AUTHORIZED_PROJECT.getCode(), QUERY_AUTHORIZED_PROJECT.getMsg());
+ }
+ }
+
+ /**
+ * import process definition
+ *
+ * @param loginUser
+ * @param file
+ * @return
+ */
+ @ApiOperation(value = "importProcessDefinition", notes= "EXPORT_PROCCESS_DEFINITION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "file", value = "RESOURCE_FILE", required = true, dataType = "MultipartFile")
+ })
+ @PostMapping(value="/importProcessDefinition")
+ public Result importProcessDefinition(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("file") MultipartFile file){
+ try{
+ logger.info("import process definition by id, login user:{}",
+ loginUser.getUserName());
+ Map result = processDefinitionService.importProcessDefinition(loginUser,file);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(IMPORT_PROCESS_DEFINE_ERROR.getMsg(),e);
+ return error(IMPORT_PROCESS_DEFINE_ERROR.getCode(), IMPORT_PROCESS_DEFINE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query all project list
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryAllProjectList", notes= "QUERY_ALL_PROJECT_LIST_NOTES")
+ @GetMapping(value = "/queryAllProjectList")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryAllProjectList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
+
+ try {
+ logger.info("login user {}, query all project list", loginUser.getUserName());
+ Map result = projectService.queryAllProjectList();
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR.getMsg(), e);
+ return error(Status.LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR.getCode(), Status.LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR.getMsg());
+ }
+ }
+
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java
new file mode 100644
index 0000000000..c06c80808f
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.QueueService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+
+/**
+ * queue controller
+ */
+@Api(tags = "QUEUE_TAG", position = 1)
+@RestController
+@RequestMapping("/queue")
+public class QueueController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(QueueController.class);
+
+ @Autowired
+ private QueueService queueService;
+
+
+ /**
+ * query queue list
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryList", notes= "QUERY_QUEUE_LIST_NOTES")
+ @GetMapping(value="/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser){
+ try{
+ logger.info("login user {}, query queue list", loginUser.getUserName());
+ Map result = queueService.queryList(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_QUEUE_LIST_ERROR.getMsg(),e);
+ return error(Status.QUERY_QUEUE_LIST_ERROR.getCode(), Status.QUERY_QUEUE_LIST_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query queue list paging
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryQueueListPaging", notes= "QUERY_QUEUE_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", dataType ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType ="Int",example = "20")
+ })
+ @GetMapping(value="/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryQueueListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize){
+ try{
+ logger.info("login user {}, query queue list,search value:{}", loginUser.getUserName(),searchVal);
+ Map result = checkPageParams(pageNo, pageSize);
+ if(result.get(Constants.STATUS) != Status.SUCCESS){
+ return returnDataListPaging(result);
+ }
+
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ result = queueService.queryList(loginUser,searchVal,pageNo,pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_QUEUE_LIST_ERROR.getMsg(),e);
+ return error(Status.QUERY_QUEUE_LIST_ERROR.getCode(), Status.QUERY_QUEUE_LIST_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * create queue
+ *
+ * @param loginUser
+ * @param queue
+ * @param queueName
+ * @return
+ */
+ @ApiOperation(value = "createQueue", notes= "CREATE_QUEUE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "queue", value = "YARN_QUEUE_NAME", required = true,dataType ="String"),
+ @ApiImplicitParam(name = "queueName", value = "QUEUE_NAME",required = true, dataType ="String")
+ })
+ @PostMapping(value = "/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createQueue(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "queue") String queue,
+ @RequestParam(value = "queueName") String queueName) {
+ logger.info("login user {}, create queue, queue: {}, queueName: {}",
+ loginUser.getUserName(), queue, queueName);
+ try {
+ Map result = queueService.createQueue(loginUser,queue,queueName);
+ return returnDataList(result);
+
+ }catch (Exception e){
+ logger.error(Status.CREATE_QUEUE_ERROR.getMsg(),e);
+ return error(Status.CREATE_QUEUE_ERROR.getCode(), Status.CREATE_QUEUE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * update queue
+ *
+ * @param loginUser
+ * @param queue
+ * @param queueName
+ * @return
+ */
+ @ApiOperation(value = "updateQueue", notes= "UPDATE_QUEUE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "QUEUE_ID", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "queue", value = "YARN_QUEUE_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "queueName", value = "QUEUE_NAME",required = true, dataType ="String")
+ })
+ @PostMapping(value = "/update")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result updateQueue(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id,
+ @RequestParam(value = "queue") String queue,
+ @RequestParam(value = "queueName") String queueName) {
+ logger.info("login user {}, update queue, id: {}, queue: {}, queueName: {}",
+ loginUser.getUserName(), id,queue, queueName);
+ try {
+ Map result = queueService.updateQueue(loginUser,id,queue,queueName);
+ return returnDataList(result);
+
+ }catch (Exception e){
+ logger.error(Status.UPDATE_QUEUE_ERROR.getMsg(),e);
+ return error(Status.UPDATE_QUEUE_ERROR.getCode(), Status.UPDATE_QUEUE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * verify queue and queue name
+ *
+ * @param loginUser
+ * @param queue
+ * @param queueName
+ * @return
+ */
+ @ApiOperation(value = "verifyQueue", notes= "VERIFY_QUEUE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "QUEUE_ID", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "queue", value = "YARN_QUEUE_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "queueName", value = "QUEUE_NAME",required = true, dataType ="String")
+ })
+ @PostMapping(value = "/verify-queue")
+ @ResponseStatus(HttpStatus.OK)
+ public Result verifyQueue(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="queue") String queue,
+ @RequestParam(value ="queueName") String queueName
+ ) {
+
+ try{
+ logger.info("login user {}, verfiy queue: {} queue name: {}",
+ loginUser.getUserName(),queue,queueName);
+ return queueService.verifyQueue(queue,queueName);
+ }catch (Exception e){
+ logger.error(Status.VERIFY_QUEUE_ERROR.getMsg(),e);
+ return error(Status.VERIFY_QUEUE_ERROR.getCode(), Status.VERIFY_QUEUE_ERROR.getMsg());
+ }
+ }
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java
new file mode 100644
index 0000000000..0070b50952
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java
@@ -0,0 +1,714 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.ResourcesService;
+import org.apache.dolphinscheduler.api.service.UdfFuncService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.enums.ResourceType;
+import org.apache.dolphinscheduler.common.enums.UdfType;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+/**
+ * resources controller
+ */
+@Api(tags = "RESOURCES_TAG", position = 1)
+@RestController
+@RequestMapping("resources")
+public class ResourcesController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(ResourcesController.class);
+
+
+ @Autowired
+ private ResourcesService resourceService;
+ @Autowired
+ private UdfFuncService udfFuncService;
+
+ /**
+ * create resource
+ *
+ * @param loginUser
+ * @param alias
+ * @param desc
+ * @param file
+ */
+ @ApiOperation(value = "createResource", notes= "CREATE_RESOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "RESOURCE_TYPE", required = true, dataType ="ResourceType"),
+ @ApiImplicitParam(name = "name", value = "RESOURCE_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "des", value = "RESOURCE_DESC", dataType ="String"),
+ @ApiImplicitParam(name = "file", value = "RESOURCE_FILE", required = true, dataType = "MultipartFile")
+ })
+ @PostMapping(value = "/create")
+ public Result createResource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "type") ResourceType type,
+ @RequestParam(value ="name")String alias,
+ @RequestParam(value = "desc", required = false) String desc,
+ @RequestParam("file") MultipartFile file) {
+ try {
+ logger.info("login user {}, create resource, type: {}, resource alias: {}, desc: {}, file: {},{}",
+ loginUser.getUserName(),type, alias, desc, file.getName(), file.getOriginalFilename());
+ return resourceService.createResource(loginUser,alias, desc,type ,file);
+ } catch (Exception e) {
+ logger.error(CREATE_RESOURCE_ERROR.getMsg(),e);
+ return error(CREATE_RESOURCE_ERROR.getCode(), CREATE_RESOURCE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * update resource
+ *
+ * @param loginUser
+ * @param alias
+ * @param desc
+ */
+ @ApiOperation(value = "createResource", notes= "CREATE_RESOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "type", value = "RESOURCE_TYPE", required = true, dataType ="ResourceType"),
+ @ApiImplicitParam(name = "name", value = "RESOURCE_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "des", value = "RESOURCE_DESC", dataType ="String"),
+ @ApiImplicitParam(name = "file", value = "RESOURCE_FILE", required = true,dataType = "MultipartFile")
+ })
+ @PostMapping(value = "/update")
+ public Result updateResource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="id") int resourceId,
+ @RequestParam(value = "type") ResourceType type,
+ @RequestParam(value ="name")String alias,
+ @RequestParam(value = "desc", required = false) String desc) {
+ try {
+ logger.info("login user {}, update resource, type: {}, resource alias: {}, desc: {}",
+ loginUser.getUserName(),type, alias, desc);
+ return resourceService.updateResource(loginUser,resourceId,alias, desc,type);
+ } catch (Exception e) {
+ logger.error(UPDATE_RESOURCE_ERROR.getMsg(),e);
+ return error(Status.UPDATE_RESOURCE_ERROR.getCode(), Status.UPDATE_RESOURCE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query resources list
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "querytResourceList", notes= "QUERY_RESOURCE_LIST_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "RESOURCE_TYPE", required = true, dataType ="ResourceType")
+ })
+ @GetMapping(value="/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result querytResourceList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="type") ResourceType type
+ ){
+ try{
+ logger.info("query resource list, login user:{}, resource type:{}", loginUser.getUserName(), type.toString());
+ Map result = resourceService.queryResourceList(loginUser, type);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_RESOURCES_LIST_ERROR.getMsg(),e);
+ return error(Status.QUERY_RESOURCES_LIST_ERROR.getCode(), Status.QUERY_RESOURCES_LIST_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query resources list paging
+ *
+ * @param loginUser
+ * @param pageNo
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "querytResourceListPaging", notes= "QUERY_RESOURCE_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "RESOURCE_TYPE", required = true, dataType ="ResourceType"),
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", dataType ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType ="Int",example = "20")
+ })
+ @GetMapping(value="/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result querytResourceListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="type") ResourceType type,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize
+ ){
+ try{
+ logger.info("query resource list, login user:{}, resource type:{}, search value:{}",
+ loginUser.getUserName(), type.toString(), searchVal);
+ Map result = checkPageParams(pageNo, pageSize);
+ if(result.get(Constants.STATUS) != Status.SUCCESS){
+ return returnDataListPaging(result);
+ }
+
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ result = resourceService.queryResourceListPaging(loginUser,type,searchVal,pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(QUERY_RESOURCES_LIST_PAGING.getMsg(),e);
+ return error(Status.QUERY_RESOURCES_LIST_PAGING.getCode(), Status.QUERY_RESOURCES_LIST_PAGING.getMsg());
+ }
+ }
+
+
+ /**
+ * delete resource
+ *
+ * @param loginUser
+ * @param resourceId
+ */
+ @ApiOperation(value = "deleteResource", notes= "DELETE_RESOURCE_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result deleteResource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="id") int resourceId
+ ) {
+ try{
+ logger.info("login user {}, delete resource id: {}",
+ loginUser.getUserName(),resourceId);
+ return resourceService.delete(loginUser,resourceId);
+ }catch (Exception e){
+ logger.error(DELETE_RESOURCE_ERROR.getMsg(),e);
+ return error(Status.DELETE_RESOURCE_ERROR.getCode(), Status.DELETE_RESOURCE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * verify resource by alias and type
+ *
+ * @param loginUser
+ * @param alias
+ * @param type
+ * @return
+ */
+ @ApiOperation(value = "verifyResourceName", notes= "VERIFY_RESOURCE_NAME_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "RESOURCE_TYPE", required = true, dataType ="ResourceType"),
+ @ApiImplicitParam(name = "name", value = "RESOURCE_NAME", required = true, dataType ="String")
+ })
+ @GetMapping(value = "/verify-name")
+ @ResponseStatus(HttpStatus.OK)
+ public Result verifyResourceName(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="name") String alias,
+ @RequestParam(value ="type") ResourceType type
+ ) {
+ try {
+ logger.info("login user {}, verfiy resource alias: {},resource type: {}",
+ loginUser.getUserName(), alias,type);
+
+ return resourceService.verifyResourceName(alias,type,loginUser);
+ } catch (Exception e) {
+ logger.error(VERIFY_RESOURCE_BY_NAME_AND_TYPE_ERROR.getMsg(), e);
+ return error(Status.VERIFY_RESOURCE_BY_NAME_AND_TYPE_ERROR.getCode(), Status.VERIFY_RESOURCE_BY_NAME_AND_TYPE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * view resource file online
+ *
+ * @param loginUser
+ * @param resourceId
+ */
+ @ApiOperation(value = "viewResource", notes= "VIEW_RESOURCE_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "skipLineNum", value = "SKIP_LINE_NUM", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "limit", value = "LIMIT", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/view")
+ public Result viewResource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int resourceId,
+ @RequestParam(value = "skipLineNum") int skipLineNum,
+ @RequestParam(value = "limit") int limit
+ ) {
+ try{
+ logger.info("login user {}, view resource : {}, skipLineNum {} , limit {}",
+ loginUser.getUserName(),resourceId,skipLineNum,limit);
+
+ return resourceService.readResource(resourceId,skipLineNum,limit);
+ }catch (Exception e){
+ logger.error(VIEW_RESOURCE_FILE_ON_LINE_ERROR.getMsg(),e);
+ return error(Status.VIEW_RESOURCE_FILE_ON_LINE_ERROR.getCode(), Status.VIEW_RESOURCE_FILE_ON_LINE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * create resource file online
+ *
+ * @param loginUser
+ * @param type
+ * @param fileName
+ * @param fileSuffix
+ * @param desc
+ * @param content
+ * @return
+ */
+ @ApiOperation(value = "onlineCreateResource", notes= "ONLINE_CREATE_RESOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "RESOURCE_TYPE", required = true, dataType ="ResourceType"),
+ @ApiImplicitParam(name = "fileName", value = "RESOURCE_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "suffix", value = "SUFFIX", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "des", value = "RESOURCE_DESC", dataType ="String"),
+ @ApiImplicitParam(name = "content", value = "CONTENT",required = true, dataType ="String")
+ })
+ @PostMapping(value = "/online-create")
+ public Result onlineCreateResource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "type") ResourceType type,
+ @RequestParam(value ="fileName")String fileName,
+ @RequestParam(value ="suffix")String fileSuffix,
+ @RequestParam(value = "desc", required = false) String desc,
+ @RequestParam(value = "content") String content
+ ) {
+ try{
+ logger.info("login user {}, online create resource! fileName : {}, type : {}, suffix : {},desc : {},content : {}",
+ loginUser.getUserName(),type,fileName,fileSuffix,desc,content);
+ if(StringUtils.isEmpty(content)){
+ logger.error("resource file contents are not allowed to be empty");
+ return error(Status.RESOURCE_FILE_IS_EMPTY.getCode(), RESOURCE_FILE_IS_EMPTY.getMsg());
+ }
+ return resourceService.onlineCreateResource(loginUser,type,fileName,fileSuffix,desc,content);
+ }catch (Exception e){
+ logger.error(CREATE_RESOURCE_FILE_ON_LINE_ERROR.getMsg(),e);
+ return error(Status.CREATE_RESOURCE_FILE_ON_LINE_ERROR.getCode(), Status.CREATE_RESOURCE_FILE_ON_LINE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * edit resource file online
+ *
+ * @param loginUser
+ * @param resourceId
+ */
+ @ApiOperation(value = "updateResourceContent", notes= "UPDATE_RESOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "content", value = "CONTENT",required = true, dataType ="String")
+ })
+ @PostMapping(value = "/update-content")
+ public Result updateResourceContent(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int resourceId,
+ @RequestParam(value = "content") String content
+ ) {
+ try{
+ logger.info("login user {}, updateProcessInstance resource : {}",
+ loginUser.getUserName(),resourceId);
+ if(StringUtils.isEmpty(content)){
+ logger.error("The resource file contents are not allowed to be empty");
+ return error(Status.RESOURCE_FILE_IS_EMPTY.getCode(), RESOURCE_FILE_IS_EMPTY.getMsg());
+ }
+ return resourceService.updateResourceContent(resourceId,content);
+ }catch (Exception e){
+ logger.error(EDIT_RESOURCE_FILE_ON_LINE_ERROR.getMsg(),e);
+ return error(Status.EDIT_RESOURCE_FILE_ON_LINE_ERROR.getCode(), Status.EDIT_RESOURCE_FILE_ON_LINE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * download resource file
+ *
+ * @param loginUser
+ * @param resourceId
+ */
+ @ApiOperation(value = "downloadResource", notes= "DOWNLOAD_RESOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/download")
+ @ResponseBody
+ public ResponseEntity downloadResource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int resourceId) {
+ try{
+ logger.info("login user {}, download resource : {}",
+ loginUser.getUserName(), resourceId);
+ Resource file = resourceService.downloadResource(resourceId);
+ if (file == null) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Status.RESOURCE_NOT_EXIST.getMsg());
+ }
+ return ResponseEntity
+ .ok()
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
+ .body(file);
+ }catch (Exception e){
+ logger.error(DOWNLOAD_RESOURCE_FILE_ERROR.getMsg(),e);
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Status.DOWNLOAD_RESOURCE_FILE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * create udf function
+ * @param loginUser
+ * @param type
+ * @param funcName
+ * @param argTypes
+ * @param database
+ * @param desc
+ * @param resourceId
+ * @return
+ */
+ @ApiOperation(value = "createUdfFunc", notes= "CREATE_UDF_FUNCTION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "UDF_TYPE", required = true, dataType ="UdfType"),
+ @ApiImplicitParam(name = "funcName", value = "FUNC_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "suffix", value = "CLASS_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "argTypes", value = "ARG_TYPES", dataType ="String"),
+ @ApiImplicitParam(name = "database", value = "DATABASE_NAME", dataType ="String"),
+ @ApiImplicitParam(name = "desc", value = "UDF_DESC", dataType ="String"),
+ @ApiImplicitParam(name = "resourceId", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100")
+
+ })
+ @PostMapping(value = "/udf-func/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createUdfFunc(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "type") UdfType type,
+ @RequestParam(value ="funcName")String funcName,
+ @RequestParam(value ="className")String className,
+ @RequestParam(value ="argTypes", required = false)String argTypes,
+ @RequestParam(value ="database", required = false)String database,
+ @RequestParam(value = "desc", required = false) String desc,
+ @RequestParam(value = "resourceId") int resourceId) {
+ logger.info("login user {}, create udf function, type: {}, funcName: {},argTypes: {} ,database: {},desc: {},resourceId: {}",
+ loginUser.getUserName(),type, funcName, argTypes,database,desc, resourceId);
+ Result result = new Result();
+
+ try {
+ return udfFuncService.createUdfFunction(loginUser,funcName,className,argTypes,database,desc,type,resourceId);
+ } catch (Exception e) {
+ logger.error(CREATE_UDF_FUNCTION_ERROR.getMsg(),e);
+ return error(Status.CREATE_UDF_FUNCTION_ERROR.getCode(), Status.CREATE_UDF_FUNCTION_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * view udf function
+ *
+ * @param loginUser
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "viewUIUdfFunction", notes= "VIEW_UDF_FUNCTION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "resourceId", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100")
+
+ })
+ @GetMapping(value = "/udf-func/update-ui")
+ @ResponseStatus(HttpStatus.OK)
+ public Result viewUIUdfFunction(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("id") int id)
+ {
+ Result result = new Result();
+ logger.info("login user {}, query udf{}",
+ loginUser.getUserName(), id);
+ try {
+ Map map = udfFuncService.queryUdfFuncDetail(id);
+ return returnDataList(map);
+ } catch (Exception e) {
+ logger.error(VIEW_UDF_FUNCTION_ERROR.getMsg(),e);
+ return error(Status.VIEW_UDF_FUNCTION_ERROR.getCode(), Status.VIEW_UDF_FUNCTION_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * updateProcessInstance udf function
+ *
+ * @param loginUser
+ * @param type
+ * @param funcName
+ * @param argTypes
+ * @param database
+ * @param desc
+ * @param resourceId
+ * @return
+ */
+ @ApiOperation(value = "updateUdfFunc", notes= "UPDATE_UDF_FUNCTION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "UDF_TYPE", required = true, dataType ="UdfType"),
+ @ApiImplicitParam(name = "funcName", value = "FUNC_NAME",required = true, dataType ="String"),
+ @ApiImplicitParam(name = "suffix", value = "CLASS_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "argTypes", value = "ARG_TYPES", dataType ="String"),
+ @ApiImplicitParam(name = "database", value = "DATABASE_NAME", dataType ="String"),
+ @ApiImplicitParam(name = "desc", value = "UDF_DESC", dataType ="String"),
+ @ApiImplicitParam(name = "id", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100")
+
+ })
+ @PostMapping(value = "/udf-func/update")
+ public Result updateUdfFunc(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int udfFuncId,
+ @RequestParam(value = "type") UdfType type,
+ @RequestParam(value ="funcName")String funcName,
+ @RequestParam(value ="className")String className,
+ @RequestParam(value ="argTypes", required = false)String argTypes,
+ @RequestParam(value ="database", required = false)String database,
+ @RequestParam(value = "desc", required = false) String desc,
+ @RequestParam(value = "resourceId") int resourceId) {
+ try {
+ logger.info("login user {}, updateProcessInstance udf function id: {},type: {}, funcName: {},argTypes: {} ,database: {},desc: {},resourceId: {}",
+ loginUser.getUserName(),udfFuncId,type, funcName, argTypes,database,desc, resourceId);
+ Map result = udfFuncService.updateUdfFunc(udfFuncId,funcName,className,argTypes,database,desc,type,resourceId);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(UPDATE_UDF_FUNCTION_ERROR.getMsg(),e);
+ return error(Status.UPDATE_UDF_FUNCTION_ERROR.getCode(), Status.UPDATE_UDF_FUNCTION_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query udf function list paging
+ *
+ * @param loginUser
+ * @param pageNo
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryUdfFuncListPaging", notes= "QUERY_UDF_FUNCTION_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", dataType ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType ="Int",example = "20")
+ })
+ @GetMapping(value="/udf-func/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryUdfFuncList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize
+ ){
+ try{
+ logger.info("query udf functions list, login user:{},search value:{}",
+ loginUser.getUserName(), searchVal);
+ Map result = checkPageParams(pageNo, pageSize);
+ if(result.get(Constants.STATUS) != Status.SUCCESS){
+ return returnDataListPaging(result);
+ }
+
+ result = udfFuncService.queryUdfFuncListPaging(loginUser,searchVal,pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(QUERY_UDF_FUNCTION_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_UDF_FUNCTION_LIST_PAGING_ERROR.getCode(), Status.QUERY_UDF_FUNCTION_LIST_PAGING_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query resource list by type
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryResourceList", notes= "QUERY_RESOURCE_LIST_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "UDF_TYPE", required = true, dataType ="UdfType")
+ })
+ @GetMapping(value="/udf-func/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryResourceList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("type") UdfType type){
+ try{
+ logger.info("query datasource list, user:{}, type:{}", loginUser.getUserName(), type.toString());
+ Map result = udfFuncService.queryResourceList(loginUser,type.ordinal());
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(QUERY_DATASOURCE_BY_TYPE_ERROR.getMsg(),e);
+ return error(Status.QUERY_DATASOURCE_BY_TYPE_ERROR.getCode(),QUERY_DATASOURCE_BY_TYPE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * verify udf function name can use or not
+ *
+ * @param loginUser
+ * @param name
+ * @return
+ */
+ @ApiOperation(value = "verifyUdfFuncName", notes= "VERIFY_UDF_FUNCTION_NAME_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name", value = "FUNC_NAME",required = true, dataType ="String")
+
+ })
+ @GetMapping(value = "/udf-func/verify-name")
+ @ResponseStatus(HttpStatus.OK)
+ public Result verifyUdfFuncName(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="name") String name
+ ) {
+ logger.info("login user {}, verfiy udf function name: {}",
+ loginUser.getUserName(),name);
+
+ try{
+
+ return udfFuncService.verifyUdfFuncByName(name);
+ }catch (Exception e){
+ logger.error(VERIFY_UDF_FUNCTION_NAME_ERROR.getMsg(),e);
+ return error(Status.VERIFY_UDF_FUNCTION_NAME_ERROR.getCode(), Status.VERIFY_UDF_FUNCTION_NAME_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete udf function
+ *
+ * @param loginUser
+ * @param udfFuncId
+ */
+ @ApiOperation(value = "deleteUdfFunc", notes= "DELETE_UDF_FUNCTION_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "RESOURCE_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/udf-func/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result deleteUdfFunc(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="id") int udfFuncId
+ ) {
+ try{
+
+ logger.info("login user {}, delete udf function id: {}", loginUser.getUserName(),udfFuncId);
+ return udfFuncService.delete(udfFuncId);
+ }catch (Exception e){
+ logger.error(DELETE_UDF_FUNCTION_ERROR.getMsg(),e);
+ return error(Status.DELETE_UDF_FUNCTION_ERROR.getCode(), Status.DELETE_UDF_FUNCTION_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * authorized file resource list
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "authorizedFile", notes= "AUTHORIZED_FILE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/authed-file")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result authorizedFile(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ try{
+ logger.info("authorized file resource, user: {}, user id:{}", loginUser.getUserName(), userId);
+ Map result = resourceService.authorizedFile(loginUser, userId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(AUTHORIZED_FILE_RESOURCE_ERROR.getMsg(),e);
+ return error(Status.AUTHORIZED_FILE_RESOURCE_ERROR.getCode(), Status.AUTHORIZED_FILE_RESOURCE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * unauthorized file resource list
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "unauthorizedFile", notes= "UNAUTHORIZED_FILE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/unauth-file")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result unauthorizedFile(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ try{
+ logger.info("resource unauthorized file, user:{}, unauthorized user id:{}", loginUser.getUserName(), userId);
+ Map result = resourceService.unauthorizedFile(loginUser, userId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(UNAUTHORIZED_FILE_RESOURCE_ERROR.getMsg(),e);
+ return error(Status.UNAUTHORIZED_FILE_RESOURCE_ERROR.getCode(), Status.UNAUTHORIZED_FILE_RESOURCE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * unauthorized udf function
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "unauthUDFFunc", notes= "UNAUTHORIZED_UDF_FUNC_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/unauth-udf-func")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result unauthUDFFunc(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ try{
+ logger.info("unauthorized udf function, login user:{}, unauthorized user id:{}", loginUser.getUserName(), userId);
+
+ Map result = resourceService.unauthorizedUDFFunction(loginUser, userId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(UNAUTHORIZED_UDF_FUNCTION_ERROR.getMsg(),e);
+ return error(Status.UNAUTHORIZED_UDF_FUNCTION_ERROR.getCode(), Status.UNAUTHORIZED_UDF_FUNCTION_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * authorized udf function
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "authUDFFunc", notes= "AUTHORIZED_UDF_FUNC_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType ="Int", example = "100")
+ })
+ @GetMapping(value = "/authed-udf-func")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result authorizedUDFFunction(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ try{
+ logger.info("auth udf function, login user:{}, auth user id:{}", loginUser.getUserName(), userId);
+ Map result = resourceService.authorizedUDFFunction(loginUser, userId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(AUTHORIZED_UDF_FUNCTION_ERROR.getMsg(),e);
+ return error(Status.AUTHORIZED_UDF_FUNCTION_ERROR.getCode(), Status.AUTHORIZED_UDF_FUNCTION_ERROR.getMsg());
+ }
+ }
+}
\ No newline at end of file
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java
new file mode 100644
index 0000000000..1d436d7d3d
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java
@@ -0,0 +1,336 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.SchedulerService;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.enums.FailureStrategy;
+import org.apache.dolphinscheduler.common.enums.Priority;
+import org.apache.dolphinscheduler.common.enums.ReleaseState;
+import org.apache.dolphinscheduler.common.enums.WarningType;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+import static org.apache.dolphinscheduler.api.utils.Constants.SESSION_USER;
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+
+/**
+ * schedule controller
+ */
+@Api(tags = "SCHEDULER_TAG", position = 13)
+@RestController
+@RequestMapping("/projects/{projectName}/schedule")
+public class SchedulerController extends BaseController {
+
+ private static final Logger logger = LoggerFactory.getLogger(SchedulerController.class);
+ public static final String DEFAULT_WARNING_TYPE = "NONE";
+ public static final String DEFAULT_NOTIFY_GROUP_ID = "1";
+ public static final String DEFAULT_FAILURE_POLICY = "CONTINUE";
+
+
+ @Autowired
+ private SchedulerService schedulerService;
+
+
+ /**
+ * create schedule
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processDefinitionId
+ * @param schedule
+ * @param warningType
+ * @param warningGroupId
+ * @param failureStrategy
+ * @return
+ */
+ @ApiOperation(value = "createSchedule", notes= "CREATE_SCHEDULE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "schedule", value = "SCHEDULE", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "warningType", value = "WARNING_TYPE", type ="WarningType"),
+ @ApiImplicitParam(name = "warningGroupId", value = "WARNING_GROUP_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "failureStrategy", value = "FAILURE_STRATEGY", type ="FailureStrategy"),
+ @ApiImplicitParam(name = "receivers", value = "RECEIVERS", type ="String"),
+ @ApiImplicitParam(name = "receiversCc", value = "RECEIVERS_CC", type ="String"),
+ @ApiImplicitParam(name = "workerGroupId", value = "WORKER_GROUP_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "processInstancePriority", value = "PROCESS_INSTANCE_PRIORITY", type ="Priority"),
+ })
+ @PostMapping("/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createSchedule(@ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam(value = "processDefinitionId") Integer processDefinitionId,
+ @RequestParam(value = "schedule") String schedule,
+ @RequestParam(value = "warningType", required = false, defaultValue = DEFAULT_WARNING_TYPE) WarningType warningType,
+ @RequestParam(value = "warningGroupId", required = false, defaultValue = DEFAULT_NOTIFY_GROUP_ID) int warningGroupId,
+ @RequestParam(value = "failureStrategy", required = false, defaultValue = DEFAULT_FAILURE_POLICY) FailureStrategy failureStrategy,
+ @RequestParam(value = "receivers", required = false) String receivers,
+ @RequestParam(value = "receiversCc", required = false) String receiversCc,
+ @RequestParam(value = "workerGroupId", required = false, defaultValue = "-1") int workerGroupId,
+ @RequestParam(value = "processInstancePriority", required = false) Priority processInstancePriority) {
+ logger.info("login user {}, project name: {}, process name: {}, create schedule: {}, warning type: {}, warning group id: {}," +
+ "failure policy: {},receivers : {},receiversCc : {},processInstancePriority : {}, workGroupId:{}",
+ loginUser.getUserName(), projectName, processDefinitionId, schedule, warningType, warningGroupId,
+ failureStrategy, receivers, receiversCc, processInstancePriority, workerGroupId);
+ try {
+ Map result = schedulerService.insertSchedule(loginUser, projectName, processDefinitionId, schedule,
+ warningType, warningGroupId, failureStrategy, receivers, receiversCc, processInstancePriority, workerGroupId);
+
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(CREATE_SCHEDULE_ERROR.getMsg(), e);
+ return error(CREATE_SCHEDULE_ERROR.getCode(), CREATE_SCHEDULE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * updateProcessInstance schedule
+ *
+ * @param loginUser
+ * @param projectName
+ * @param id
+ * @param schedule
+ * @param warningType
+ * @param warningGroupId
+ * @param failureStrategy
+ * @return
+ */
+ @ApiOperation(value = "updateSchedule", notes= "UPDATE_SCHEDULE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "SCHEDULE_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "schedule", value = "SCHEDULE", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "warningType", value = "WARNING_TYPE", type ="WarningType"),
+ @ApiImplicitParam(name = "warningGroupId", value = "WARNING_GROUP_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "failureStrategy", value = "FAILURE_STRATEGY", type ="FailureStrategy"),
+ @ApiImplicitParam(name = "receivers", value = "RECEIVERS", type ="String"),
+ @ApiImplicitParam(name = "receiversCc", value = "RECEIVERS_CC", type ="String"),
+ @ApiImplicitParam(name = "workerGroupId", value = "WORKER_GROUP_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "processInstancePriority", value = "PROCESS_INSTANCE_PRIORITY", type ="Priority"),
+ })
+ @PostMapping("/update")
+ public Result updateSchedule(@ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam(value = "id") Integer id,
+ @RequestParam(value = "schedule") String schedule,
+ @RequestParam(value = "warningType", required = false, defaultValue = DEFAULT_WARNING_TYPE) WarningType warningType,
+ @RequestParam(value = "warningGroupId", required = false) int warningGroupId,
+ @RequestParam(value = "failureStrategy", required = false, defaultValue = "END") FailureStrategy failureStrategy,
+ @RequestParam(value = "receivers", required = false) String receivers,
+ @RequestParam(value = "receiversCc", required = false) String receiversCc,
+ @RequestParam(value = "workerGroupId", required = false, defaultValue = "-1") int workerGroupId,
+ @RequestParam(value = "processInstancePriority", required = false) Priority processInstancePriority) {
+ logger.info("login user {}, project name: {},id: {}, updateProcessInstance schedule: {}, notify type: {}, notify mails: {}, " +
+ "failure policy: {},receivers : {},receiversCc : {},processInstancePriority : {},workerGroupId:{}",
+ loginUser.getUserName(), projectName, id, schedule, warningType, warningGroupId, failureStrategy,
+ receivers, receiversCc, processInstancePriority, workerGroupId);
+
+ try {
+ Map result = schedulerService.updateSchedule(loginUser, projectName, id, schedule,
+ warningType, warningGroupId, failureStrategy, receivers, receiversCc, null, processInstancePriority, workerGroupId);
+ return returnDataList(result);
+
+ } catch (Exception e) {
+ logger.error(UPDATE_SCHEDULE_ERROR.getMsg(), e);
+ return error(Status.UPDATE_SCHEDULE_ERROR.getCode(), Status.UPDATE_SCHEDULE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * publish schedule setScheduleState
+ *
+ * @param loginUser
+ * @param projectName
+ * @param id
+ * @return
+ * @throws Exception
+ */
+ @ApiOperation(value = "online", notes= "ONLINE_SCHEDULE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "SCHEDULE_ID", required = true, dataType = "Int", example = "100")
+ })
+ @PostMapping("/online")
+ public Result online(@ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable("projectName") String projectName,
+ @RequestParam("id") Integer id) {
+ logger.info("login user {}, schedule setScheduleState, project name: {}, id: {}",
+ loginUser.getUserName(), projectName, id);
+ try {
+ Map result = schedulerService.setScheduleState(loginUser, projectName, id, ReleaseState.ONLINE);
+ return returnDataList(result);
+
+ } catch (Exception e) {
+ logger.error(PUBLISH_SCHEDULE_ONLINE_ERROR.getMsg(), e);
+ return error(Status.PUBLISH_SCHEDULE_ONLINE_ERROR.getCode(), Status.PUBLISH_SCHEDULE_ONLINE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * offline schedule
+ *
+ * @param loginUser
+ * @param projectName
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "offline", notes= "OFFLINE_SCHEDULE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "SCHEDULE_ID", required = true, dataType = "Int", example = "100")
+ })
+ @PostMapping("/offline")
+ public Result offline(@ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable("projectName") String projectName,
+ @RequestParam("id") Integer id) {
+ logger.info("login user {}, schedule offline, project name: {}, process definition id: {}",
+ loginUser.getUserName(), projectName, id);
+
+ try {
+ Map result = schedulerService.setScheduleState(loginUser, projectName, id, ReleaseState.OFFLINE);
+ return returnDataList(result);
+
+ } catch (Exception e) {
+ logger.error(OFFLINE_SCHEDULE_ERROR.getMsg(), e);
+ return error(Status.OFFLINE_SCHEDULE_ERROR.getCode(), Status.OFFLINE_SCHEDULE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query schedule list paging
+ *
+ * @param loginUser
+ * @param projectName
+ * @param processDefinitionId
+ * @return
+ */
+ @ApiOperation(value = "queryScheduleListPaging", notes= "QUERY_SCHEDULE_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processDefinitionId", value = "PROCESS_DEFINITION_ID", required = true,dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", type = "String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType = "Int", example = "100")
+
+ })
+ @GetMapping("/list-paging")
+ public Result queryScheduleListPaging(@ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam Integer processDefinitionId,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam("pageSize") Integer pageSize) {
+ logger.info("login user {}, query schedule, project name: {}, process definition id: {}",
+ loginUser.getUserName(), projectName, processDefinitionId);
+ try {
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ Map result = schedulerService.querySchedule(loginUser, projectName, processDefinitionId, searchVal, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(QUERY_SCHEDULE_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_SCHEDULE_LIST_PAGING_ERROR.getCode(), Status.QUERY_SCHEDULE_LIST_PAGING_ERROR.getMsg());
+ }
+
+ }
+
+ /**
+ * delete schedule by id
+ *
+ * @param loginUser
+ * @param projectName
+ * @param scheduleId
+ * @return
+ */
+ @ApiOperation(value = "deleteScheduleById", notes= "OFFLINE_SCHEDULE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "scheduleId", value = "SCHEDULE_ID", required = true, dataType = "Int", example = "100")
+ })
+ @GetMapping(value="/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result deleteScheduleById(@RequestAttribute(value = SESSION_USER) User loginUser,
+ @PathVariable String projectName,
+ @RequestParam("scheduleId") Integer scheduleId
+ ){
+ try{
+ logger.info("delete schedule by id, login user:{}, project name:{}, schedule id:{}",
+ loginUser.getUserName(), projectName, scheduleId);
+ Map result = schedulerService.deleteScheduleById(loginUser, projectName, scheduleId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(DELETE_SCHEDULE_CRON_BY_ID_ERROR.getMsg(),e);
+ return error(Status.DELETE_SCHEDULE_CRON_BY_ID_ERROR.getCode(), Status.DELETE_SCHEDULE_CRON_BY_ID_ERROR.getMsg());
+ }
+ }
+ /**
+ * query schedule list
+ *
+ * @param loginUser
+ * @param projectName
+ * @return
+ */
+ @ApiOperation(value = "queryScheduleList", notes= "QUERY_SCHEDULE_LIST_NOTES")
+ @PostMapping("/list")
+ public Result queryScheduleList(@ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName) {
+ try {
+ logger.info("login user {}, query schedule list, project name: {}",
+ loginUser.getUserName(), projectName);
+ Map result = schedulerService.queryScheduleList(loginUser, projectName);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(QUERY_SCHEDULE_LIST_ERROR.getMsg(), e);
+ return error(Status.QUERY_SCHEDULE_LIST_ERROR.getCode(), Status.QUERY_SCHEDULE_LIST_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * preview schedule
+ *
+ * @param loginUser
+ * @param projectName
+ * @param schedule
+ * @return
+ */
+ @ApiOperation(value = "previewSchedule", notes= "PREVIEW_SCHEDULE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "schedule", value = "SCHEDULE", dataType = "String", example = "{'startTime':'2019-06-10 00:00:00','endTime':'2019-06-13 00:00:00','crontab':'0 0 3/6 * * ? *'}"),
+ })
+ @PostMapping("/preview")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result previewSchedule(@ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam(value = "schedule") String schedule
+ ){
+ logger.info("login user {}, project name: {}, preview schedule: {}",
+ loginUser.getUserName(), projectName, schedule);
+ try {
+ Map result = schedulerService.previewSchedule(loginUser, projectName, schedule);
+ return returnDataList(result);
+ } catch (Exception e) {
+ logger.error(PREVIEW_SCHEDULE_ERROR.getMsg(), e);
+ return error(PREVIEW_SCHEDULE_ERROR.getCode(), PREVIEW_SCHEDULE_ERROR.getMsg());
+ }
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TaskInstanceController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TaskInstanceController.java
new file mode 100644
index 0000000000..99213358cd
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TaskInstanceController.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.service.TaskInstanceService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.enums.ExecutionStatus;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.*;
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+/**
+ * task instance controller
+ */
+@Api(tags = "TASK_INSTANCE_TAG", position = 11)
+@RestController
+@RequestMapping("/projects/{projectName}/task-instance")
+public class TaskInstanceController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(TaskInstanceController.class);
+
+ @Autowired
+ TaskInstanceService taskInstanceService;
+
+
+ /**
+ * query task list paging
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryTaskListPaging", notes= "QUERY_TASK_INSTANCE_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID",required = false, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", type ="String"),
+ @ApiImplicitParam(name = "taskName", value = "TASK_NAME", type ="String"),
+ @ApiImplicitParam(name = "stateType", value = "EXECUTION_STATUS", type ="ExecutionStatus"),
+ @ApiImplicitParam(name = "host", value = "HOST", type ="String"),
+ @ApiImplicitParam(name = "startDate", value = "START_DATE", type ="String"),
+ @ApiImplicitParam(name = "endDate", value = "END_DATE", type ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType = "Int", example = "20")
+ })
+ @GetMapping("/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryTaskListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
+ @RequestParam(value = "processInstanceId", required = false, defaultValue = "0") Integer processInstanceId,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam(value = "taskName", required = false) String taskName,
+ @RequestParam(value = "stateType", required = false) ExecutionStatus stateType,
+ @RequestParam(value = "host", required = false) String host,
+ @RequestParam(value = "startDate", required = false) String startTime,
+ @RequestParam(value = "endDate", required = false) String endTime,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam("pageSize") Integer pageSize){
+
+ try{
+ logger.info("query task instance list, project name:{},process instance:{}, search value:{},task name:{}, state type:{}, host:{}, start:{}, end:{}",
+ projectName, processInstanceId, searchVal, taskName, stateType, host, startTime, endTime);
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ Map result = taskInstanceService.queryTaskListPaging(
+ loginUser, projectName, processInstanceId, taskName, startTime, endTime, searchVal, stateType, host, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_TASK_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_TASK_LIST_PAGING_ERROR.getCode(), Status.QUERY_TASK_LIST_PAGING_ERROR.getMsg());
+ }
+
+ }
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TaskRecordController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TaskRecordController.java
new file mode 100644
index 0000000000..dabcf62b80
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TaskRecordController.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.service.TaskRecordService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.User;
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+/**
+ * data quality controller
+ */
+@ApiIgnore
+@RestController
+@RequestMapping("/projects/task-record")
+public class TaskRecordController extends BaseController{
+
+
+ private static final Logger logger = LoggerFactory.getLogger(TaskRecordController.class);
+
+
+ @Autowired
+ TaskRecordService taskRecordService;
+
+ /**
+ * query task record list paging
+ *
+ * @param loginUser
+ * @return
+ */
+ @GetMapping("/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryTaskRecordListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "taskName", required = false) String taskName,
+ @RequestParam(value = "state", required = false) String state,
+ @RequestParam(value = "sourceTable", required = false) String sourceTable,
+ @RequestParam(value = "destTable", required = false) String destTable,
+ @RequestParam(value = "taskDate", required = false) String taskDate,
+ @RequestParam(value = "startDate", required = false) String startTime,
+ @RequestParam(value = "endDate", required = false) String endTime,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam("pageSize") Integer pageSize
+ ){
+
+ try{
+ logger.info("query task record list, task name:{}, state :{}, taskDate: {}, start:{}, end:{}",
+ taskName, state, taskDate, startTime, endTime);
+ Map result = taskRecordService.queryTaskRecordListPaging(false, taskName, startTime, taskDate, sourceTable, destTable, endTime,state, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_TASK_RECORD_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_TASK_RECORD_LIST_PAGING_ERROR.getCode(), Status.QUERY_TASK_RECORD_LIST_PAGING_ERROR.getMsg());
+ }
+
+ }
+
+ /**
+ * query history task record list paging
+ *
+ * @param loginUser
+ * @return
+ */
+ @GetMapping("/history-list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryHistoryTaskRecordListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "taskName", required = false) String taskName,
+ @RequestParam(value = "state", required = false) String state,
+ @RequestParam(value = "sourceTable", required = false) String sourceTable,
+ @RequestParam(value = "destTable", required = false) String destTable,
+ @RequestParam(value = "taskDate", required = false) String taskDate,
+ @RequestParam(value = "startDate", required = false) String startTime,
+ @RequestParam(value = "endDate", required = false) String endTime,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam("pageSize") Integer pageSize
+ ){
+
+ try{
+ logger.info("query hisotry task record list, task name:{}, state :{}, taskDate: {}, start:{}, end:{}",
+ taskName, state, taskDate, startTime, endTime);
+ Map result = taskRecordService.queryTaskRecordListPaging(true, taskName, startTime, taskDate, sourceTable, destTable, endTime,state, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_TASK_RECORD_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_TASK_RECORD_LIST_PAGING_ERROR.getCode(), Status.QUERY_TASK_RECORD_LIST_PAGING_ERROR.getMsg());
+ }
+
+ }
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TenantController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TenantController.java
new file mode 100644
index 0000000000..2ec74398c2
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TenantController.java
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.TenantService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+
+/**
+ * tenant controller
+ */
+@Api(tags = "TENANT_TAG", position = 1)
+@RestController
+@RequestMapping("/tenant")
+public class TenantController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(TenantController.class);
+
+
+ @Autowired
+ private TenantService tenantService;
+
+ /**
+ * create tenant
+ *
+ * @param loginUser
+ * @param tenantCode
+ * @param tenantName
+ * @param queueId
+ * @param desc
+ * @return
+ */
+ @ApiOperation(value = "createTenant", notes= "CREATE_TENANT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "tenantCode", value = "TENANT_CODE", required = true, dataType = "String"),
+ @ApiImplicitParam(name = "tenantName", value = "TENANT_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "queueId", value = "QUEUE_ID", required = true, dataType ="Int",example = "100"),
+ @ApiImplicitParam(name = "desc", value = "TENANT_DESC", dataType ="String")
+
+ })
+ @PostMapping(value = "/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createTenant(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "tenantCode") String tenantCode,
+ @RequestParam(value = "tenantName") String tenantName,
+ @RequestParam(value = "queueId") int queueId,
+ @RequestParam(value = "desc",required = false) String desc) {
+ logger.info("login user {}, create tenant, tenantCode: {}, tenantName: {}, queueId: {}, desc: {}",
+ loginUser.getUserName(), tenantCode, tenantName, queueId,desc);
+ try {
+ Map result = tenantService.createTenant(loginUser,tenantCode,tenantName,queueId,desc);
+ return returnDataList(result);
+
+ }catch (Exception e){
+ logger.error(Status.CREATE_TENANT_ERROR.getMsg(),e);
+ return error(Status.CREATE_TENANT_ERROR.getCode(), Status.CREATE_TENANT_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * query tenant list paging
+ *
+ * @param loginUser
+ * @param pageNo
+ * @param searchVal
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryTenantlistPaging", notes= "QUERY_TENANT_LIST_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", dataType ="String"),
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType ="Int",example = "20")
+ })
+ @GetMapping(value="/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryTenantlistPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize){
+ logger.info("login user {}, list paging, pageNo: {}, searchVal: {}, pageSize: {}",
+ loginUser.getUserName(),pageNo,searchVal,pageSize);
+ try{
+ Map result = checkPageParams(pageNo, pageSize);
+ if(result.get(Constants.STATUS) != Status.SUCCESS){
+ return returnDataListPaging(result);
+ }
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ result = tenantService.queryTenantList(loginUser, searchVal, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_TENANT_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_TENANT_LIST_PAGING_ERROR.getCode(), Status.QUERY_TENANT_LIST_PAGING_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * tenant list
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryTenantlist", notes= "QUERY_TENANT_LIST_NOTES")
+ @GetMapping(value="/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryTenantlist(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser){
+ logger.info("login user {}, query tenant list");
+ try{
+ Map result = tenantService.queryTenantList(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_TENANT_LIST_ERROR.getMsg(),e);
+ return error(Status.QUERY_TENANT_LIST_ERROR.getCode(), Status.QUERY_TENANT_LIST_ERROR.getMsg());
+ }
+ }
+
+
+
+ /**
+ * udpate tenant
+ *
+ * @param loginUser
+ * @param tenantCode
+ * @param tenantName
+ * @param queueId
+ * @param desc
+ * @return
+ */
+ @ApiOperation(value = "updateTenant", notes= "UPDATE_TENANT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "ID", value = "TENANT_ID", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "tenantCode", value = "TENANT_CODE", required = true, dataType = "String"),
+ @ApiImplicitParam(name = "tenantName", value = "TENANT_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "queueId", value = "QUEUE_ID", required = true, dataType ="Int", example = "100"),
+ @ApiImplicitParam(name = "desc", value = "TENANT_DESC", type ="String")
+
+ })
+ @PostMapping(value = "/update")
+ @ResponseStatus(HttpStatus.OK)
+ public Result updateTenant(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id,
+ @RequestParam(value = "tenantCode") String tenantCode,
+ @RequestParam(value = "tenantName") String tenantName,
+ @RequestParam(value = "queueId") int queueId,
+ @RequestParam(value = "desc",required = false) String desc) {
+ logger.info("login user {}, updateProcessInstance tenant, tenantCode: {}, tenantName: {}, queueId: {}, desc: {}",
+ loginUser.getUserName(), tenantCode, tenantName, queueId,desc);
+ try {
+ Map result = tenantService.updateTenant(loginUser,id,tenantCode, tenantName, queueId, desc);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.UPDATE_TENANT_ERROR.getMsg(),e);
+ return error(Status.UPDATE_TENANT_ERROR.getCode(), Status.UPDATE_TENANT_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete tenant by id
+ *
+ * @param loginUser
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "deleteTenantById", notes= "DELETE_TENANT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "ID", value = "TENANT_ID", required = true, dataType ="Int", example = "100")
+
+ })
+ @PostMapping(value = "/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result deleteTenantById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id) {
+ logger.info("login user {}, delete tenant, tenantCode: {},", loginUser.getUserName(), id);
+ try {
+ Map result = tenantService.deleteTenantById(loginUser,id);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.DELETE_TENANT_BY_ID_ERROR.getMsg(),e);
+ return error(Status.DELETE_TENANT_BY_ID_ERROR.getCode(), Status.DELETE_TENANT_BY_ID_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * verify tenant code
+ *
+ * @param loginUser
+ * @param tenantCode
+ * @return
+ */
+ @ApiOperation(value = "verifyTenantCode", notes= "VERIFY_TENANT_CODE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "tenantCode", value = "TENANT_CODE", required = true, dataType = "String")
+ })
+ @GetMapping(value = "/verify-tenant-code")
+ @ResponseStatus(HttpStatus.OK)
+ public Result verifyTenantCode(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="tenantCode") String tenantCode
+ ) {
+
+ try{
+ logger.info("login user {}, verfiy tenant code: {}",
+ loginUser.getUserName(),tenantCode);
+ return tenantService.verifyTenantCode(tenantCode);
+ }catch (Exception e){
+ logger.error(Status.VERIFY_TENANT_CODE_ERROR.getMsg(),e);
+ return error(Status.VERIFY_TENANT_CODE_ERROR.getCode(), Status.VERIFY_TENANT_CODE_ERROR.getMsg());
+ }
+ }
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
new file mode 100644
index 0000000000..f8aab7c97c
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
@@ -0,0 +1,454 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.UsersService;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+
+/**
+ * user controller
+ */
+@Api(tags = "USERS_TAG" , position = 14)
+@RestController
+@RequestMapping("/users")
+public class UsersController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(UsersController.class);
+
+ @Autowired
+ private UsersService usersService;
+
+ /**
+ * create user
+ *
+ * @param loginUser
+ * @param userName
+ * @param userPassword
+ * @param email
+ * @param tenantId
+ * @param phone
+ * @return
+ */
+ @ApiOperation(value = "createUser", notes= "CREATE_USER_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userName", value = "USER_NAME",type = "String"),
+ @ApiImplicitParam(name = "userPassword", value = "USER_PASSWORD", type ="String"),
+ @ApiImplicitParam(name = "tenantId", value = "TENANT_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "queue", value = "QUEUE", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "email", value = "EMAIL", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "phone", value = "PHONE", dataType = "Int", example = "100")
+ })
+ @PostMapping(value = "/create")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Result createUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userName") String userName,
+ @RequestParam(value = "userPassword") String userPassword,
+ @RequestParam(value = "tenantId") int tenantId,
+ @RequestParam(value = "queue",required = false,defaultValue = "") String queue,
+ @RequestParam(value = "email") String email,
+ @RequestParam(value = "phone", required = false) String phone) {
+ logger.info("login user {}, create user, userName: {}, email: {}, tenantId: {}, userPassword: {}, phone: {}, user queue: {}",
+ loginUser.getUserName(), userName, email, tenantId, Constants.PASSWORD_DEFAULT, phone,queue);
+
+ try {
+ Map result = usersService.createUser(loginUser, userName, userPassword,email,tenantId, phone,queue);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.CREATE_USER_ERROR.getMsg(),e);
+ return error(Status.CREATE_USER_ERROR.getCode(), Status.CREATE_USER_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query user list paging
+ *
+ * @param loginUser
+ * @param pageNo
+ * @param searchVal
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryUserList", notes= "QUERY_USER_LIST_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "pageNo", value = "PAGE_NO",dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", type ="String"),
+ @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", type ="String")
+ })
+ @GetMapping(value="/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryUserList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize){
+ logger.info("login user {}, list user paging, pageNo: {}, searchVal: {}, pageSize: {}",
+ loginUser.getUserName(),pageNo,searchVal,pageSize);
+ try{
+ Map result = checkPageParams(pageNo, pageSize);
+ if(result.get(Constants.STATUS) != Status.SUCCESS){
+ return returnDataListPaging(result);
+ }
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ result = usersService.queryUserList(loginUser, searchVal, pageNo, pageSize);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.QUERY_USER_LIST_PAGING_ERROR.getMsg(),e);
+ return error(Status.QUERY_USER_LIST_PAGING_ERROR.getCode(), Status.QUERY_USER_LIST_PAGING_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * update user
+ *
+ * @param loginUser
+ * @param id
+ * @param userName
+ * @param userPassword
+ * @param email
+ * @param tenantId
+ * @param phone
+ * @return
+ */
+ @ApiOperation(value = "updateUser", notes= "UPDATE_USER_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "USER_ID",dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "userName", value = "USER_NAME",type = "String"),
+ @ApiImplicitParam(name = "userPassword", value = "USER_PASSWORD", type ="String"),
+ @ApiImplicitParam(name = "tenantId", value = "TENANT_ID", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "queue", value = "QUEUE", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "email", value = "EMAIL", dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "phone", value = "PHONE", dataType = "Int", example = "100")
+ })
+ @PostMapping(value = "/update")
+ @ResponseStatus(HttpStatus.OK)
+ public Result updateUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id,
+ @RequestParam(value = "userName") String userName,
+ @RequestParam(value = "userPassword") String userPassword,
+ @RequestParam(value = "queue",required = false,defaultValue = "") String queue,
+ @RequestParam(value = "email") String email,
+ @RequestParam(value = "tenantId") int tenantId,
+ @RequestParam(value = "phone", required = false) String phone) {
+ logger.info("login user {}, updateProcessInstance user, userName: {}, email: {}, tenantId: {}, userPassword: {}, phone: {}, user queue: {}",
+ loginUser.getUserName(), userName, email, tenantId, Constants.PASSWORD_DEFAULT, phone,queue);
+ try {
+ Map result = usersService.updateUser(id, userName, userPassword, email, tenantId, phone, queue);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.UPDATE_USER_ERROR.getMsg(),e);
+ return error(Status.UPDATE_USER_ERROR.getCode(), Status.UPDATE_USER_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete user by id
+ * @param loginUser
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "delUserById", notes= "DELETE_USER_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "USER_ID",dataType = "Int", example = "100")
+ })
+ @PostMapping(value = "/delete")
+ @ResponseStatus(HttpStatus.OK)
+ public Result delUserById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id") int id) {
+ logger.info("login user {}, delete user, userId: {},", loginUser.getUserName(), id);
+ try {
+ Map result = usersService.deleteUserById(loginUser, id);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.DELETE_USER_BY_ID_ERROR.getMsg(),e);
+ return error(Status.DELETE_USER_BY_ID_ERROR.getCode(), Status.DELETE_USER_BY_ID_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * grant project
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "grantProject", notes= "GRANT_PROJECT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID",dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "projectIds", value = "PROJECT_IDS",type = "String")
+ })
+ @PostMapping(value = "/grant-project")
+ @ResponseStatus(HttpStatus.OK)
+ public Result grantProject(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "projectIds") String projectIds) {
+ logger.info("login user {}, grant project, userId: {},projectIds : {}", loginUser.getUserName(), userId,projectIds);
+ try {
+ Map result = usersService.grantProject(loginUser, userId, projectIds);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.GRANT_PROJECT_ERROR.getMsg(),e);
+ return error(Status.GRANT_PROJECT_ERROR.getCode(), Status.GRANT_PROJECT_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * grant resource
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "grantResource", notes= "GRANT_RESOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID",dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "resourceIds", value = "RESOURCE_IDS",type = "String")
+ })
+ @PostMapping(value = "/grant-file")
+ @ResponseStatus(HttpStatus.OK)
+ public Result grantResource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "resourceIds") String resourceIds) {
+ logger.info("login user {}, grant project, userId: {},resourceIds : {}", loginUser.getUserName(), userId,resourceIds);
+ try {
+ Map result = usersService.grantResources(loginUser, userId, resourceIds);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.GRANT_RESOURCE_ERROR.getMsg(),e);
+ return error(Status.GRANT_RESOURCE_ERROR.getCode(), Status.GRANT_RESOURCE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * grant udf function
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "grantUDFFunc", notes= "GRANT_UDF_FUNC_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID",dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "udfIds", value = "UDF_IDS",type = "String")
+ })
+ @PostMapping(value = "/grant-udf-func")
+ @ResponseStatus(HttpStatus.OK)
+ public Result grantUDFFunc(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "udfIds") String udfIds) {
+ logger.info("login user {}, grant project, userId: {},resourceIds : {}", loginUser.getUserName(), userId,udfIds);
+ try {
+ Map result = usersService.grantUDFFunction(loginUser, userId, udfIds);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.GRANT_UDF_FUNCTION_ERROR.getMsg(),e);
+ return error(Status.GRANT_UDF_FUNCTION_ERROR.getCode(), Status.GRANT_UDF_FUNCTION_ERROR.getMsg());
+ }
+ }
+
+
+
+ /**
+ * grant datasource
+ *
+ * @param loginUser
+ * @param userId
+ * @return
+ */
+ @ApiOperation(value = "grantDataSource", notes= "GRANT_DATASOURCE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID",dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "datasourceIds", value = "DATASOURCE_IDS",type = "String")
+ })
+ @PostMapping(value = "/grant-datasource")
+ @ResponseStatus(HttpStatus.OK)
+ public Result grantDataSource(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "datasourceIds") String datasourceIds) {
+ logger.info("login user {}, grant project, userId: {},projectIds : {}", loginUser.getUserName(),userId,datasourceIds);
+ try {
+ Map result = usersService.grantDataSource(loginUser, userId, datasourceIds);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.GRANT_DATASOURCE_ERROR.getMsg(),e);
+ return error(Status.GRANT_DATASOURCE_ERROR.getCode(), Status.GRANT_DATASOURCE_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * get user info
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "getUserInfo", notes= "GET_USER_INFO_NOTES")
+ @GetMapping(value="/get-user-info")
+ @ResponseStatus(HttpStatus.OK)
+ public Result getUserInfo(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser){
+ logger.info("login user {},get user info : {}", loginUser.getUserName());
+ try{
+ Map result = usersService.getUserInfo(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.GET_USER_INFO_ERROR.getMsg(),e);
+ return error(Status.GET_USER_INFO_ERROR.getCode(), Status.GET_USER_INFO_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * user list no paging
+ *
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "listUser", notes= "LIST_USER_NOTES")
+ @GetMapping(value="/list")
+ @ResponseStatus(HttpStatus.OK)
+ public Result listUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser){
+ logger.info("login user {}, user list");
+ try{
+ Map result = usersService.queryAllGeneralUsers(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.USER_LIST_ERROR.getMsg(),e);
+ return error(Status.USER_LIST_ERROR.getCode(), Status.USER_LIST_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * user list no paging
+ *
+ * @param loginUser
+ * @return
+ */
+ @GetMapping(value="/list-all")
+ @ResponseStatus(HttpStatus.OK)
+ public Result listAll(@RequestAttribute(value = Constants.SESSION_USER) User loginUser){
+ logger.info("login user {}, user list");
+ try{
+ Map result = usersService.queryUserList(loginUser);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.USER_LIST_ERROR.getMsg(),e);
+ return error(Status.USER_LIST_ERROR.getCode(), Status.USER_LIST_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * verify username
+ *
+ * @param loginUser
+ * @param userName
+ * @return
+ */
+ @ApiOperation(value = "verifyUserName", notes= "VERIFY_USER_NAME_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userName", value = "USER_NAME",type = "String")
+ })
+ @GetMapping(value = "/verify-user-name")
+ @ResponseStatus(HttpStatus.OK)
+ public Result verifyUserName(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value ="userName") String userName
+ ) {
+ try{
+
+ logger.info("login user {}, verfiy user name: {}",
+ loginUser.getUserName(),userName);
+ return usersService.verifyUserName(userName);
+ }catch (Exception e){
+ logger.error(Status.VERIFY_USERNAME_ERROR.getMsg(),e);
+ return error(Status.VERIFY_USERNAME_ERROR.getCode(), Status.VERIFY_USERNAME_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * unauthorized user
+ *
+ * @param loginUser
+ * @param alertgroupId
+ * @return
+ */
+ @ApiOperation(value = "unauthorizedUser", notes= "UNAUTHORIZED_USER_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "alertgroupId", value = "ALERT_GROUP_ID",type = "String")
+ })
+ @GetMapping(value = "/unauth-user")
+ @ResponseStatus(HttpStatus.OK)
+ public Result unauthorizedUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("alertgroupId") Integer alertgroupId) {
+ try{
+ logger.info("unauthorized user, login user:{}, alert group id:{}",
+ loginUser.getUserName(), alertgroupId);
+ Map result = usersService.unauthorizedUser(loginUser, alertgroupId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.UNAUTHORIZED_USER_ERROR.getMsg(),e);
+ return error(Status.UNAUTHORIZED_USER_ERROR.getCode(), Status.UNAUTHORIZED_USER_ERROR.getMsg());
+ }
+ }
+
+
+ /**
+ * authorized user
+ *
+ * @param loginUser
+ * @param alertgroupId
+ * @return
+ */
+ @ApiOperation(value = "authorizedUser", notes= "AUTHORIZED_USER_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "alertgroupId", value = "ALERT_GROUP_ID",type = "String")
+ })
+ @GetMapping(value = "/authed-user")
+ @ResponseStatus(HttpStatus.OK)
+ public Result authorizedUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("alertgroupId") Integer alertgroupId) {
+ try{
+ logger.info("authorized user , login user:{}, alert group id:{}",
+ loginUser.getUserName(), alertgroupId);
+ Map result = usersService.authorizedUser(loginUser, alertgroupId);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.AUTHORIZED_USER_ERROR.getMsg(),e);
+ return error(Status.AUTHORIZED_USER_ERROR.getCode(), Status.AUTHORIZED_USER_ERROR.getMsg());
+ }
+ }
+
+
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkerGroupController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkerGroupController.java
new file mode 100644
index 0000000000..d0c934ea6d
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkerGroupController.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.controller;
+
+
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.service.WorkerGroupService;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.User;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.dolphinscheduler.api.utils.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+/**
+ * worker group controller
+ */
+@Api(tags = "WORKER_GROUP_TAG", position = 1)
+@RestController
+@RequestMapping("/worker-group")
+public class WorkerGroupController extends BaseController{
+
+ private static final Logger logger = LoggerFactory.getLogger(WorkerGroupController.class);
+
+
+ @Autowired
+ WorkerGroupService workerGroupService;
+
+
+ /**
+ * create or update a worker group
+ * @param loginUser
+ * @param id
+ * @param name
+ * @param ipList
+ * @return
+ */
+ @ApiOperation(value = "saveWorkerGroup", notes= "CREATE_WORKER_GROUP_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "WORKER_GROUP_ID", dataType = "Int", example = "10", defaultValue = "0"),
+ @ApiImplicitParam(name = "name", value = "WORKER_GROUP_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "ipList", value = "WORKER_IP_LIST", required = true, dataType ="String")
+ })
+ @PostMapping(value = "/save")
+ @ResponseStatus(HttpStatus.OK)
+ public Result saveWorkerGroup(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "id", required = false, defaultValue = "0") int id,
+ @RequestParam(value = "name") String name,
+ @RequestParam(value = "ipList") String ipList
+ ) {
+ logger.info("save worker group: login user {}, id:{}, name: {}, ipList: {} ",
+ loginUser.getUserName(), id, name, ipList);
+
+ try {
+ Map result = workerGroupService.saveWorkerGroup(id, name, ipList);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.SAVE_ERROR.getMsg(),e);
+ return error(Status.SAVE_ERROR.getCode(), Status.SAVE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query worker groups paging
+ * @param loginUser
+ * @param pageNo
+ * @param searchVal
+ * @param pageSize
+ * @return
+ */
+ @ApiOperation(value = "queryAllWorkerGroupsPaging", notes= "QUERY_WORKER_GROUP_PAGING_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "WORKER_GROUP_ID", dataType = "Int", example = "10", defaultValue = "0"),
+ @ApiImplicitParam(name = "name", value = "WORKER_GROUP_NAME", required = true, dataType ="String"),
+ @ApiImplicitParam(name = "ipList", value = "WORKER_IP_LIST", required = true, dataType ="String")
+ })
+ @GetMapping(value = "/list-paging")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryAllWorkerGroupsPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam(value = "searchVal", required = false) String searchVal,
+ @RequestParam("pageSize") Integer pageSize
+ ) {
+ logger.info("query all worker group paging: login user {}, pageNo:{}, pageSize:{}, searchVal:{}",
+ loginUser.getUserName() , pageNo, pageSize, searchVal);
+
+ try {
+ searchVal = ParameterUtils.handleEscapes(searchVal);
+ Map result = workerGroupService.queryAllGroupPaging(pageNo, pageSize, searchVal);
+ return returnDataListPaging(result);
+ }catch (Exception e){
+ logger.error(Status.SAVE_ERROR.getMsg(),e);
+ return error(Status.SAVE_ERROR.getCode(), Status.SAVE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * query all worker groups
+ * @param loginUser
+ * @return
+ */
+ @ApiOperation(value = "queryAllWorkerGroups", notes= "QUERY_WORKER_GROUP_LIST_NOTES")
+ @GetMapping(value = "/all-groups")
+ @ResponseStatus(HttpStatus.OK)
+ public Result queryAllWorkerGroups(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser
+ ) {
+ logger.info("query all worker group: login user {}",
+ loginUser.getUserName() );
+
+ try {
+ Map result = workerGroupService.queryAllGroup();
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.SAVE_ERROR.getMsg(),e);
+ return error(Status.SAVE_ERROR.getCode(), Status.SAVE_ERROR.getMsg());
+ }
+ }
+
+ /**
+ * delete worker group by id
+ * @param loginUser
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "deleteById", notes= "DELETE_WORKER_GROUP_BY_ID_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "WORKER_GROUP_ID", required = true, dataType = "Int", example = "10"),
+
+ })
+ @GetMapping(value = "/delete-by-id")
+ @ResponseStatus(HttpStatus.OK)
+ public Result deleteById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("id") Integer id
+ ) {
+ logger.info("delete worker group: login user {}, id:{} ",
+ loginUser.getUserName() , id);
+
+ try {
+ Map result = workerGroupService.deleteWorkerGroupById(id);
+ return returnDataList(result);
+ }catch (Exception e){
+ logger.error(Status.SAVE_ERROR.getMsg(),e);
+ return error(Status.SAVE_ERROR.getCode(), Status.SAVE_ERROR.getMsg());
+ }
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/CommandStateCount.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/CommandStateCount.java
new file mode 100644
index 0000000000..3c3c31bfce
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/CommandStateCount.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.dto;
+
+import org.apache.dolphinscheduler.common.enums.CommandType;
+
+/**
+ * command state count
+ */
+public class CommandStateCount {
+
+ private int errorCount;
+ private int normalCount;
+ private CommandType commandState;
+
+ public CommandStateCount(){}
+ public CommandStateCount(int errorCount, int normalCount, CommandType commandState) {
+ this.errorCount = errorCount;
+ this.normalCount = normalCount;
+ this.commandState = commandState;
+ }
+
+ public int getErrorCount() {
+ return errorCount;
+ }
+
+ public void setErrorCount(int errorCount) {
+ this.errorCount = errorCount;
+ }
+
+ public int getNormalCount() {
+ return normalCount;
+ }
+
+ public void setNormalCount(int normalCount) {
+ this.normalCount = normalCount;
+ }
+
+ public CommandType getCommandState() {
+ return commandState;
+ }
+
+ public void setCommandState(CommandType commandState) {
+ this.commandState = commandState;
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/DefineUserDto.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/DefineUserDto.java
new file mode 100644
index 0000000000..539dc71a5e
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/DefineUserDto.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.dto;
+
+import org.apache.dolphinscheduler.dao.entity.DefinitionGroupByUser;
+
+import java.util.List;
+
+/**
+ *
+ */
+public class DefineUserDto {
+
+ private int count;
+
+ private List userList;
+
+ public DefineUserDto(List defineGroupByUsers) {
+
+ for(DefinitionGroupByUser define : defineGroupByUsers){
+ count += define.getCount();
+ }
+ this.userList = defineGroupByUsers;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+ public List getUserList() {
+ return userList;
+ }
+
+ public void setUserList(List userList) {
+ this.userList = userList;
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/ScheduleParam.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/ScheduleParam.java
new file mode 100644
index 0000000000..538786e63d
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/ScheduleParam.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.dto;
+
+import java.util.Date;
+
+/**
+ * schedule parameters
+ * 调度参数
+ */
+public class ScheduleParam {
+ private Date startTime;
+ private Date endTime;
+ private String crontab;
+
+ public ScheduleParam() {
+ }
+
+ public ScheduleParam(Date startTime, Date endTime, String crontab) {
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.crontab = crontab;
+ }
+
+ public Date getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(Date startTime) {
+ this.startTime = startTime;
+ }
+
+ public Date getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(Date endTime) {
+ this.endTime = endTime;
+ }
+
+ public String getCrontab() {
+ return crontab;
+ }
+
+ public void setCrontab(String crontab) {
+ this.crontab = crontab;
+ }
+
+
+ @Override
+ public String toString() {
+ return "ScheduleParam{" +
+ "startTime=" + startTime +
+ ", endTime=" + endTime +
+ ", crontab='" + crontab + '\'' +
+ '}';
+ }
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/TaskCountDto.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/TaskCountDto.java
new file mode 100644
index 0000000000..b6b587bde6
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/TaskCountDto.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dolphinscheduler.api.dto;
+
+import org.apache.dolphinscheduler.common.enums.ExecutionStatus;
+import org.apache.dolphinscheduler.dao.entity.ExecuteStatusCount;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * task count dto
+ */
+public class TaskCountDto {
+
+ /**
+ * total count
+ */
+ private int totalCount;
+
+ /**
+ *
+ */
+ private List