Browse Source

rename project and doc

pull/2/head
qiaozhanwei 5 years ago
parent
commit
d09a2d07c9
  1. 22
      docs/en_US/EasyScheduler-FAQ.md
  2. 2
      docs/en_US/SUMMARY.md
  3. 56
      docs/en_US/backend-deployment.md
  4. 4
      docs/en_US/backend-development.md
  5. 8
      docs/en_US/frontend-deployment.md
  6. 8
      docs/en_US/frontend-development.md
  7. 2
      docs/en_US/quick-start.md
  8. 4
      docs/en_US/system-manual.md
  9. 6
      docs/en_US/upgrade.md
  10. 22
      docs/zh_CN/EasyScheduler-FAQ.md
  11. 2
      docs/zh_CN/SUMMARY.md
  12. 12
      docs/zh_CN/任务插件开发.md
  13. 8
      docs/zh_CN/前端开发文档.md
  14. 8
      docs/zh_CN/前端部署文档.md
  15. 6
      docs/zh_CN/升级文档.md
  16. 4
      docs/zh_CN/后端开发文档.md
  17. 56
      docs/zh_CN/后端部署文档.md
  18. 2
      docs/zh_CN/快速上手.md
  19. 4
      docs/zh_CN/系统使用手册.md
  20. 129
      dolphinscheduler-alert/pom.xml
  21. 40
      dolphinscheduler-alert/src/main/assembly/package.xml
  22. 89
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java
  23. 55
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java
  24. 57
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java
  25. 36
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/MsgManager.java
  26. 142
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java
  27. 157
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java
  28. 246
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java
  29. 131
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/ExcelUtils.java
  30. 35
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/FuncUtils.java
  31. 68
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/JSONUtils.java
  32. 456
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java
  33. 193
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/PropertyUtils.java
  34. 0
      dolphinscheduler-alert/src/main/resources/alert.properties
  35. 31
      dolphinscheduler-alert/src/main/resources/alert_logback.xml
  36. 0
      dolphinscheduler-alert/src/main/resources/application_alert.properties
  37. 0
      dolphinscheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl
  38. 119
      dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java
  39. 231
      dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java
  40. 219
      dolphinscheduler-api/pom.xml
  41. 74
      dolphinscheduler-api/src/main/assembly/package.xml
  42. 37
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java
  43. 57
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/CombinedApplicationServer.java
  44. 115
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java
  45. 509
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/ServiceModelToSwagger2MapperImpl.java
  46. 55
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/SwaggerConfig.java
  47. 184
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AccessTokenController.java
  48. 252
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AlertGroupController.java
  49. 272
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/BaseController.java
  50. 199
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataAnalysisController.java
  51. 458
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataSourceController.java
  52. 199
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ExecutorController.java
  53. 106
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
  54. 147
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoginController.java
  55. 131
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/MonitorController.java
  56. 491
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java
  57. 367
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessInstanceController.java
  58. 304
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java
  59. 200
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java
  60. 714
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java
  61. 336
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java
  62. 97
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TaskInstanceController.java
  63. 113
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TaskRecordController.java
  64. 245
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TenantController.java
  65. 454
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
  66. 170
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkerGroupController.java
  67. 60
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/CommandStateCount.java
  68. 55
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/DefineUserDto.java
  69. 72
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/ScheduleParam.java
  70. 135
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/TaskCountDto.java
  71. 50
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/TaskStateCount.java
  72. 103
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/gantt/GanttDto.java
  73. 138
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/gantt/Task.java
  74. 171
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/treeview/Instance.java
  75. 84
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/treeview/TreeViewDto.java
  76. 40
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/ExecuteType.java
  77. 266
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  78. 29
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/DruidStatFilter.java
  79. 34
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/DruidStatViewServlet.java
  80. 111
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LoginHandlerInterceptor.java
  81. 134
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/log/LogClient.java
  82. 181
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AccessTokenService.java
  83. 294
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AlertGroupService.java
  84. 89
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/BaseDAGService.java
  85. 130
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/BaseService.java
  86. 416
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/DataAnalysisService.java
  87. 690
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/DataSourceService.java
  88. 540
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ExecutorService.java
  89. 91
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java
  90. 127
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/MonitorService.java
  91. 1120
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionService.java
  92. 723
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessInstanceService.java
  93. 396
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProjectService.java
  94. 259
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/QueueService.java
  95. 897
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ResourcesService.java
  96. 594
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SchedulerService.java
  97. 150
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SessionService.java
  98. 134
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TaskInstanceService.java
  99. 85
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TaskRecordService.java
  100. 300
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TenantService.java
  101. Some files were not shown because too many files have changed in this diff Show More

22
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

2
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

56
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
```

4
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

8
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;

8
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

2
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
<p align="center">
<img src="https://user-images.githubusercontent.com/48329107/61701549-ee738000-ad70-11e9-8d75-87ce04a0152f.png" width="60%" />

4
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<NameValuePair> parameters = new ArrayList<NameValuePair>();

6
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

22
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

2
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)
* 系统版本升级文档

12
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**

8
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

8
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;

6
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. 后端服务升级

4
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

56
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
```

2
docs/zh_CN/快速上手.md

@ -1,7 +1,7 @@
# 快速上手
* 管理员用户登录
>地址:192.168.xx.xx:8888 用户名密码:admin/escheduler123
>地址:192.168.xx.xx:8888 用户名密码:admin/dolphinscheduler123
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/login.jpg" width="60%" />

4
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<NameValuePair> parameters = new ArrayList<NameValuePair>();

129
dolphinscheduler-alert/pom.xml

@ -0,0 +1,129 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<artifactId>dolphinscheduler-alert</artifactId>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!--excel poi-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-dao</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/package.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

40
dolphinscheduler-alert/src/main/assembly/package.xml

@ -0,0 +1,40 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>cluster</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.json</include>
<include>**/*.ftl</include>
</includes>
<outputDirectory>conf</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>dolphinscheduler-alert-${project.version}.jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<excludes>
<exclude>javax.servlet:servlet-api</exclude>
<exclude>org.eclipse.jetty.aggregate:jetty-all</exclude>
<exclude>org.slf4j:slf4j-log4j12</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>

89
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<Alert> 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();
}
}

55
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<String,Object> send(List<String> receviersList,List<String> 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<String,Object> send(List<String> receviersList,String title,String content,ShowType showType){
return MailUtils.sendMails(receviersList,title, content, showType);
}
}

57
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<String,Object> send(Alert alert, String token){
Map<String,Object> retMap = new HashMap<>();
retMap.put(Constants.STATUS, false);
String agentId = EnterpriseWeChatUtils.enterpriseWeChatAgentId;
String users = EnterpriseWeChatUtils.enterpriseWeChatUsers;
List<String> 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;
}
}

36
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);
}
}

142
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<Alert> alertList;
private AlertDao alertDao;
public AlertSender(){}
public AlertSender(List<Alert> alertList, AlertDao alertDao){
super();
this.alertList = alertList;
this.alertDao = alertDao;
}
public void run() {
List<User> users;
Map<String, Object> retMaps = null;
for(Alert alert:alertList){
users = alertDao.listUserByAlertgroupId(alert.getAlertGroupId());
// receiving group list
List<String> receviersList = new ArrayList<String>();
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<String> receviersCcList = new ArrayList<String>();
// 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<String> getReciversForSMS(List<User> users){
List<String> list = new ArrayList<>();
for (User user : users){
list.add(user.getPhone());
}
return list;
}
}

157
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 = "<tr>";
public static final String TD = "<td>";
public static final String TD_END = "</td>";
public static final String TR_END = "</tr>";
public static final String TITLE = "title";
public static final String CONTENT = "content";
public static final String TH = "<th>";
public static final String TH_END = "</th>";
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";
}

246
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<String, Object> map = JSON.parseObject(resp,
new TypeToken<Map<String, Object>>() {
}.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<String> 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<String> 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<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class);
StringBuilder contents = new StringBuilder(200);
for (LinkedHashMap mapItems : mapItemsList){
Set<Map.Entry<String, String>> entries = mapItems.entrySet();
Iterator<Map.Entry<String, String>> iterator = entries.iterator();
StringBuilder t = new StringBuilder(String.format("`%s`%s",title,Constants.MARKDOWN_ENTER));
while (iterator.hasNext()){
Map.Entry<String, String> 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<String> 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;
}
}

131
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<LinkedHashMap> 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<String, Object> headerMap = itemsList.get(0);
List<String> headerList = new ArrayList<>();
Iterator<Map.Entry<String, Object>> iter = headerMap.entrySet().iterator();
while (iter.hasNext()){
Map.Entry<String, Object> 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<String, Object> 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);
}
}
}
}
}

35
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<String> 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();
}
}

68
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 <T>
* @return
*/
public static <T> List<T> toList(String json, Class<T> clazz) {
if (StringUtils.isEmpty(json)) {
return null;
}
try {
return JSONArray.parseArray(json, clazz);
} catch (Exception e) {
logger.error("JSONArray.parseArray exception!",e);
}
return null;
}
}

456
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<String,Object> sendMails(Collection<String> 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<String,Object> sendMails(Collection<String> receivers, Collection<String> receiversCc, String title, String content, ShowType showType) {
Map<String,Object> 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<LinkedHashMap> 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<Map.Entry<String, String>> entries = mapItems.entrySet();
Iterator<Map.Entry<String, String>> iterator = entries.iterator();
StringBuilder t = new StringBuilder(Constants.TR);
StringBuilder cs = new StringBuilder(Constants.TR);
while (iterator.hasNext()){
Map.Entry<String, String> 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<String> 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<String> receivers,Collection<String> 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<String> 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<String> 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<String, Object> getStringObjectMap(String title, String content, ShowType showType, Map<String, Object> 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<String> receivers, Map<String, Object> 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<String,String> 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;
}
}

193
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 <T>
* @return get enum value
*/
public <T extends Enum<T>> T getEnum(String key, Class<T> type,
T defaultValue) {
String val = getString(key);
return val == null ? defaultValue : Enum.valueOf(type, val);
}
}

0
escheduler-alert/src/main/resources/alert.properties → dolphinscheduler-alert/src/main/resources/alert.properties

31
dolphinscheduler-alert/src/main/resources/alert_logback.xml

@ -0,0 +1,31 @@
<!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
<configuration scan="true" scanPeriod="120 seconds"> <!--debug="true" -->
<property name="log.base" value="logs" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
[%level] %date{yyyy-MM-dd HH:mm:ss.SSS} %logger{96}:[%line] - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="ALERTLOGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.base}/dolphinscheduler-alert.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.base}/dolphinscheduler-alert.%d{yyyy-MM-dd_HH}.%i.log</fileNamePattern>
<maxHistory>20</maxHistory>
<maxFileSize>64MB</maxFileSize>
</rollingPolicy>
<encoder>
<pattern>
[%level] %date{yyyy-MM-dd HH:mm:ss.SSS} %logger{96}:[%line] - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="ALERTLOGFILE"/>
</root>
</configuration>

0
escheduler-alert/src/main/resources/application_alert.properties → dolphinscheduler-alert/src/main/resources/application_alert.properties

0
escheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl → dolphinscheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl

119
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<String> listUserId = Arrays.asList(PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USERS).split(","));
// Please change
private String partyId = "2";
private Collection<String> 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" +
">事 项:<font color='info'>开会</font> <br>" +
">组织者:@miglioguan \n" +
">参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang \n" +
"> \n" +
">会议室:<font color='info'>广州TIT 1楼 301</font> \n" +
">日 期:<font color='warning'>2018年5月18日</font> \n" +
">时 间:<font color='comment'>上午9:00-11:00</font> \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();
}
}
}

231
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<Alert> 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<String, Object> map1 = new LinkedHashMap<>();
map1.put("mysql服务名称","mysql200");
map1.put("mysql地址","192.168.xx.xx");
map1.put("端口","3306");
map1.put("期间内没有使用索引的查询数握","80");
map1.put("数据库客户端连接数","190");
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>();
map2.put("mysql服务名称","mysql210");
map2.put("mysql地址","192.168.xx.xx");
map2.put("端口","3306");
map2.put("期间内没有使用索引的查询数握","10");
map2.put("数据库客户端连接数","90");
List<LinkedHashMap<String, Object>> 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<User> 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<String,String> 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);
}
}
}

219
dolphinscheduler-api/pom.xml

@ -0,0 +1,219 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<artifactId>dolphinscheduler-api</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-alert</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-server</artifactId>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</exclusion>
<exclusion>
<groupId>com.google</groupId>
<artifactId>netty</artifactId>
</exclusion>
<exclusion>
<artifactId>leveldbjni-all</artifactId>
<groupId>org.fusesource.leveldbjni</groupId>
</exclusion>
<exclusion>
<artifactId>protobuf-java</artifactId>
<groupId>com.google.protobuf</groupId>
</exclusion>
</exclusions>
</dependency>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
<exclusion>
<artifactId>log4j-to-slf4j</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- use jetty -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-server</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<exclusions>
<exclusion>
<artifactId>c3p0</artifactId>
<groupId>c3p0</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-rpc</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/package.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

74
dolphinscheduler-api/src/main/assembly/package.xml

@ -0,0 +1,74 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>cluster</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.json</include>
</includes>
<outputDirectory>conf</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.parent.basedir}/dolphinscheduler-common/src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.json</include>
</includes>
<outputDirectory>conf</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.parent.basedir}/dolphinscheduler-common/src/main/resources/bin</directory>
<includes>
<include>*.*</include>
</includes>
<directoryMode>755</directoryMode>
<outputDirectory>bin</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.parent.basedir}/dolphinscheduler-dao/src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.json</include>
</includes>
<outputDirectory>conf</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.parent.basedir}/dolphinscheduler-api/src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.json</include>
</includes>
<outputDirectory>conf</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>dolphinscheduler-api-${project.version}.jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<excludes>
<exclude>javax.servlet:servlet-api</exclude>
<exclude>org.eclipse.jetty.aggregate:jetty-all</exclude>
<exclude>org.slf4j:slf4j-log4j12</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>

37
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);
}
}

57
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();
}
}

115
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);
}
}

509
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<String> list2 = from.getConsumes();
if (list2 != null) {
swagger.setConsumes(new ArrayList<String>(list2));
} else {
swagger.setConsumes(null);
}
List<String> list3 = from.getProduces();
if (list3 != null) {
swagger.setProduces(new ArrayList<String>(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<String> tagsSet = new HashSet<>(1);
if(from.getTags() != null && from.getTags().size() > 0){
List<String> list = new ArrayList<String>(tagsSet.size());
Iterator<String> 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<String> set1 = from.getConsumes();
if (set1 != null) {
operation.setConsumes(new ArrayList<String>(set1));
} else {
operation.setConsumes(null);
}
Set<String> set2 = from.getProduces();
if (set2 != null) {
operation.setProduces(new ArrayList<String>(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<Tag> tagSetToTagList(Set<springfox.documentation.service.Tag> set) {
if (set == null) {
return null;
}
List<Tag> list = new ArrayList<Tag>(set.size());
for (springfox.documentation.service.Tag tag : set) {
list.add(mapTag(tag));
}
return list;
}
protected List<Scheme> stringSetToSchemeList(Set<String> set) {
if (set == null) {
return null;
}
List<Scheme> list = new ArrayList<Scheme>(set.size());
for (String string : set) {
list.add(Enum.valueOf(Scheme.class, string));
}
return list;
}
protected List<Parameter> parameterListToParameterList(List<springfox.documentation.service.Parameter> list) {
if (list == null) {
return null;
}
List<Parameter> list1 = new ArrayList<Parameter>(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<String, Model> modelsFromApiListings(Multimap<String, ApiListing> apiListings) {
Map<String, springfox.documentation.schema.Model> 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<String, Collection<Example>> each : source.getExamples().asMap().entrySet()) {
// Optional<Example> 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<String, Function<String, ? extends Property>> typeFactory
// = ImmutableMap.<String, Function<String, ? extends Property>>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<String, Function<String, ? extends Property>> 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<ModelReference, String>() {
// @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 <T extends Property> Function<String, T> newInstanceOf(final Class<T> clazz) {
// return new Function<String, T>() {
// @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<String> defaultOrdering(Map<String, ModelProperty> properties) {
// return Ordering.from(byPosition(properties)).compound(byName());
// }
//
// private static Function<String, ? extends Property> voidOrRef(final String typeName) {
// return new Function<String, Property>() {
// @Override
// public Property apply(String input) {
// if (typeName.equalsIgnoreCase("void")) {
// return null;
// }
// return new RefProperty(typeName);
// }
// };
// }
//
// private static Function<String, ? extends Property> bytePropertyFactory() {
// return new Function<String, Property>() {
// @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<String, ? extends Property> filePropertyFactory() {
// return new Function<String, Property>() {
// @Override
// public Property apply(String input) {
// return new FileProperty();
// }
// };
// }
//
// private static Comparator<String> byName() {
// return new Comparator<String>() {
// @Override
// public int compare(String first, String second) {
// return first.compareTo(second);
// }
// };
// }
//
// private static Comparator<String> byPosition(final Map<String, ModelProperty> modelProperties) {
// return new Comparator<String>() {
// @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<Map.Entry<String, ModelProperty>> voidProperties() {
// return new Predicate<Map.Entry<String, ModelProperty>>() {
// @Override
// public boolean apply(Map.Entry<String, ModelProperty> 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));
// }
}

55
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 <br/>
*
*/
@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();
}
}

184
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

252
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

272
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<String, Object> checkPageParams(int pageNo, int pageSize) {
Map<String, Object> 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<String, Object> 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<String, Object> result) {
Status status = (Status) result.get(Constants.STATUS);
if (status == Status.SUCCESS) {
result.put(Constants.MSG, Status.SUCCESS.getMsg());
PageInfo<Resource> pageInfo = (PageInfo<Resource>) 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<String, Object> 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<String, Object> 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<String, Object> 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;
}
}

199
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

458
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

199
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<String, Object> 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 instancepause, 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

106
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());
}
}
}

147
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());
}
}
}

131
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

491
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

367
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

304
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

200
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

714
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

336
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

97
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<String, Object> 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());
}
}
}

113
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<String, Object> 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<String, Object> 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());
}
}
}

245
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

454
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

170
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}

60
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;
}
}

55
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<DefinitionGroupByUser> userList;
public DefineUserDto(List<DefinitionGroupByUser> 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<DefinitionGroupByUser> getUserList() {
return userList;
}
public void setUserList(List<DefinitionGroupByUser> userList) {
this.userList = userList;
}
}

72
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 + '\'' +
'}';
}
}

135
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<TaskStateCount> taskCountDtos;
public TaskCountDto(List<ExecuteStatusCount> taskInstanceStateCounts) {
countTaskDtos(taskInstanceStateCounts);
}
private void countTaskDtos(List<ExecuteStatusCount> taskInstanceStateCounts){
int submitted_success = 0;
int running_exeution = 0;
int ready_pause = 0;
int pause = 0;
int ready_stop = 0;
int stop = 0;
int failure = 0;
int success = 0;
int need_fault_tolerance = 0;
int kill = 0;
int waitting_thread = 0;
int waitting_depend = 0;
for(ExecuteStatusCount taskInstanceStateCount : taskInstanceStateCounts){
ExecutionStatus status = taskInstanceStateCount.getExecutionStatus();
totalCount += taskInstanceStateCount.getCount();
switch (status){
case SUBMITTED_SUCCESS:
submitted_success += taskInstanceStateCount.getCount();
break;
case RUNNING_EXEUTION:
running_exeution += taskInstanceStateCount.getCount();
break;
case READY_PAUSE:
ready_pause += taskInstanceStateCount.getCount();
break;
case PAUSE:
pause += taskInstanceStateCount.getCount();
break;
case READY_STOP:
ready_stop += taskInstanceStateCount.getCount();
break;
case STOP:
stop += taskInstanceStateCount.getCount();
break;
case FAILURE:
failure += taskInstanceStateCount.getCount();
break;
case SUCCESS:
success += taskInstanceStateCount.getCount();
break;
case NEED_FAULT_TOLERANCE:
failure += taskInstanceStateCount.getCount();
break;
case KILL:
kill += taskInstanceStateCount.getCount();
break;
case WAITTING_THREAD:
kill += taskInstanceStateCount.getCount();
break;
case WAITTING_DEPEND:
kill += taskInstanceStateCount.getCount();
break;
default:
break;
}
}
this.taskCountDtos = new ArrayList<>();
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.SUBMITTED_SUCCESS, submitted_success));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.RUNNING_EXEUTION, running_exeution));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.READY_PAUSE, ready_pause));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.PAUSE, pause));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.READY_STOP, ready_stop));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.STOP, stop));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.FAILURE, failure));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.SUCCESS, success));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.NEED_FAULT_TOLERANCE, need_fault_tolerance));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.KILL, kill));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.WAITTING_THREAD, waitting_thread));
this.taskCountDtos.add(new TaskStateCount(ExecutionStatus.WAITTING_DEPEND, waitting_depend));
}
public List<TaskStateCount> getTaskCountDtos(){
return taskCountDtos;
}
public void setTaskCountDtos(List<TaskStateCount> taskCountDtos) {
this.taskCountDtos = taskCountDtos;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
}

50
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/TaskStateCount.java

@ -0,0 +1,50 @@
/*
* 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;
/**
* task state count
*/
public class TaskStateCount {
private int count;
private ExecutionStatus taskStateType;
public TaskStateCount(ExecutionStatus taskStateType, int count) {
this.taskStateType = taskStateType;
this.count = count;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public ExecutionStatus getTaskStateType() {
return taskStateType;
}
public void setTaskStateType(ExecutionStatus taskStateType) {
this.taskStateType = taskStateType;
}
}

103
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/gantt/GanttDto.java

@ -0,0 +1,103 @@
/*
* 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.gantt;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* gantt DTO
* 甘特图 DTO
*/
public class GanttDto {
/**
* height
* 高度
*/
private int height;
/**
* tasks list
* 任务集合
*/
private List<Task> tasks = new ArrayList<>();
/**
* task name list
* 任务名称
*/
private List<String> taskNames;
/**
* task status map
* 任务状态
*/
private Map<String,String> taskStatus;
public GanttDto(){
this.taskStatus = new HashMap<>();
taskStatus.put("success","success");
}
public GanttDto(int height, List<Task> tasks, List<String> taskNames){
this();
this.height = height;
this.tasks = tasks;
this.taskNames = taskNames;;
}
public GanttDto(int height, List<Task> tasks, List<String> taskNames, Map<String, String> taskStatus) {
this.height = height;
this.tasks = tasks;
this.taskNames = taskNames;
this.taskStatus = taskStatus;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public List<Task> getTasks() {
return tasks;
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
}
public List<String> getTaskNames() {
return taskNames;
}
public void setTaskNames(List<String> taskNames) {
this.taskNames = taskNames;
}
public Map<String, String> getTaskStatus() {
return taskStatus;
}
public void setTaskStatus(Map<String, String> taskStatus) {
this.taskStatus = taskStatus;
}
}

138
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/gantt/Task.java

@ -0,0 +1,138 @@
/*
* 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.gantt;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Task
* 任务
*/
public class Task {
/**
* task name
* 任务名称
*/
private String taskName;
/**
* task start date
* 任务开始时间
*/
private List<Long> startDate = new ArrayList<>();
/**
* task end date
* 任务结束时间
*/
private List<Long> endDate = new ArrayList<>();
/**
* task execution date
* 任务执行时间
*/
private Date executionDate;
/**
* task iso start
* 任务开始时间
*/
private Date isoStart;
/**
* task iso end
* 任务结束时间
*/
private Date isoEnd;
/**
* task status
* 执行状态
*/
private String status;
/**
* task duration
* 运行时长
*/
private String duration;
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public List<Long> getStartDate() {
return startDate;
}
public void setStartDate(List<Long> startDate) {
this.startDate = startDate;
}
public List<Long> getEndDate() {
return endDate;
}
public void setEndDate(List<Long> endDate) {
this.endDate = endDate;
}
public Date getExecutionDate() {
return executionDate;
}
public void setExecutionDate(Date executionDate) {
this.executionDate = executionDate;
}
public Date getIsoStart() {
return isoStart;
}
public void setIsoStart(Date isoStart) {
this.isoStart = isoStart;
}
public Date getIsoEnd() {
return isoEnd;
}
public void setIsoEnd(Date isoEnd) {
this.isoEnd = isoEnd;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
}

171
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/treeview/Instance.java

@ -0,0 +1,171 @@
/*
* 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.treeview;
import java.util.Date;
/**
* Instance
*/
public class Instance {
private int id;
/**
* node name
* 节点名称
*/
private String name;
/**
* node type
* 节点类型
*/
private String type;
/**
* node status
* 状态
*/
private String state;
/**
* node start time
* 开始时间
*/
private Date startTime;
/**
* node end time
* 结束时间
*/
private Date endTime;
/**
* node running on which host
* 运行机器
*/
private String host;
/**
* node duration
* 运行时长
*/
private String duration;
private int subflowId;
public Instance(){}
public Instance(int id,String name, String type){
this.id = id;
this.name = name;
this.type = type;
}
public Instance(int id,String name, String type,String state,Date startTime, Date endTime, String host, String duration,int subflowId) {
this.id = id;
this.name = name;
this.type = type;
this.state = state;
this.startTime = startTime;
this.endTime = endTime;
this.host = host;
this.duration = duration;
this.subflowId = subflowId;
}
public Instance(int id,String name, String type,String state,Date startTime, Date endTime, String host, String duration) {
this(id, name, type, state, startTime, endTime,host,duration,0);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
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 getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public int getSubflowId() {
return subflowId;
}
public void setSubflowId(int subflowId) {
this.subflowId = subflowId;
}
}

84
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/treeview/TreeViewDto.java

@ -0,0 +1,84 @@
/*
* 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.treeview;
import java.util.ArrayList;
import java.util.List;
/**
* TreeView
*/
public class TreeViewDto {
/**
* name
*/
private String name;
/**
* type
*/
private String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
* instances list
* 实例列表
*/
private List<Instance> instances = new ArrayList<>();
/**
* children
*/
private List<TreeViewDto> children = new ArrayList<>();
public List<Instance> getInstances() {
return instances;
}
public void setInstances(List<Instance> instances) {
this.instances = instances;
}
public List<TreeViewDto> getChildren() {
return children;
}
public void setChildren(List<TreeViewDto> children) {
this.children = children;
}
}

40
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/ExecuteType.java

@ -0,0 +1,40 @@
/*
* 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.enums;
/**
* execute type
*/
public enum ExecuteType {
/**
* 操作类型
* 1.重跑 2.恢复暂停 3.恢复失败 4.停止 5.暂停
*/
NONE,REPEAT_RUNNING, RECOVER_SUSPENDED_PROCESS, START_FAILURE_TASK_PROCESS, STOP, PAUSE;
public static ExecuteType getEnum(int value){
for (ExecuteType e: ExecuteType.values()) {
if(e.ordinal() == value) {
return e;
}
}
return null;//For values out of enum scope
}
}

266
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java

@ -0,0 +1,266 @@
/*
* 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.enums;
/**
* status enum
*/
public enum Status {
SUCCESS(0, "success"),
REQUEST_PARAMS_NOT_VALID_ERROR(10001, "request parameter {0} is not valid"),
TASK_TIMEOUT_PARAMS_ERROR(10002, "task timeout parameter is not valid"),
USER_NAME_EXIST(10003, "user name already exists"),
USER_NAME_NULL(10004,"user name is null"),
// DB_OPERATION_ERROR(10005, "database operation error"),
HDFS_OPERATION_ERROR(10006, "hdfs operation error"),
UPDATE_FAILED(10007, "updateProcessInstance failed"),
TASK_INSTANCE_NOT_FOUND(10008, "task instance not found"),
TENANT_NAME_EXIST(10009, "tenant code already exists"),
USER_NOT_EXIST(10010, "user {0} not exists"),
ALERT_GROUP_NOT_EXIST(10011, "alarm group not found"),
ALERT_GROUP_EXIST(10012, "alarm group already exists"),
USER_NAME_PASSWD_ERROR(10013,"user name or password error"),
LOGIN_SESSION_FAILED(10014,"create session failed!"),
DATASOURCE_EXIST(10015, "data source name already exists"),
DATASOURCE_CONNECT_FAILED(10016, "data source connection failed"),
TENANT_NOT_EXIST(10017, "tenant not exists"),
PROJECT_NOT_FOUNT(10018, "project {0} not found "),
PROJECT_ALREADY_EXISTS(10019, "project {0} already exists"),
TASK_INSTANCE_NOT_EXISTS(10020, "task instance {0} does not exist"),
TASK_INSTANCE_NOT_SUB_WORKFLOW_INSTANCE(10021, "task instance {0} is not sub process instance"),
SCHEDULE_CRON_NOT_EXISTS(10022, "scheduler crontab {0} does not exist"),
SCHEDULE_CRON_ONLINE_FORBID_UPDATE(10023, "online status does not allow updateProcessInstance operations"),
SCHEDULE_CRON_CHECK_FAILED(10024, "scheduler crontab expression validation failure: {0}"),
MASTER_NOT_EXISTS(10025, "master does not exist"),
SCHEDULE_STATUS_UNKNOWN(10026, "unknown command: {0}"),
CREATE_ALERT_GROUP_ERROR(10027,"create alert group error"),
QUERY_ALL_ALERTGROUP_ERROR(10028,"query all alertgroup error"),
LIST_PAGING_ALERT_GROUP_ERROR(10029,"list paging alert group error"),
UPDATE_ALERT_GROUP_ERROR(10030,"updateProcessInstance alert group error"),
DELETE_ALERT_GROUP_ERROR(10031,"delete alert group error"),
ALERT_GROUP_GRANT_USER_ERROR(10032,"alert group grant user error"),
CREATE_DATASOURCE_ERROR(10033,"create datasource error"),
UPDATE_DATASOURCE_ERROR(10034,"updateProcessInstance datasource error"),
QUERY_DATASOURCE_ERROR(10035,"query datasource error"),
CONNECT_DATASOURCE_FAILURE(10036,"connect datasource failure"),
CONNECTION_TEST_FAILURE(10037,"connection test failure"),
DELETE_DATA_SOURCE_FAILURE(10038,"delete data source failure"),
VERFIY_DATASOURCE_NAME_FAILURE(10039,"verfiy datasource name failure"),
UNAUTHORIZED_DATASOURCE(10040,"unauthorized datasource"),
AUTHORIZED_DATA_SOURCE(10041,"authorized data source"),
LOGIN_SUCCESS(10042,"login success"),
USER_LOGIN_FAILURE(10043,"user login failure"),
LIST_WORKERS_ERROR(10044,"list workers error"),
LIST_MASTERS_ERROR(10045,"list masters error"),
UPDATE_PROJECT_ERROR(10046,"updateProcessInstance project error"),
QUERY_PROJECT_DETAILS_BY_ID_ERROR(10047,"query project details by id error"),
CREATE_PROJECT_ERROR(10048,"create project error"),
LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR(10049,"login user query project list paging error"),
DELETE_PROJECT_ERROR(10050,"delete project error"),
QUERY_UNAUTHORIZED_PROJECT_ERROR(10051,"query unauthorized project error"),
QUERY_AUTHORIZED_PROJECT(10052,"query authorized project"),
QUERY_QUEUE_LIST_ERROR(10053,"query queue list error"),
CREATE_RESOURCE_ERROR(10054,"create resource error"),
UPDATE_RESOURCE_ERROR(10055,"updateProcessInstance resource error"),
QUERY_RESOURCES_LIST_ERROR(10056,"query resources list error"),
QUERY_RESOURCES_LIST_PAGING(10057,"query resources list paging"),
DELETE_RESOURCE_ERROR(10058,"delete resource error"),
VERIFY_RESOURCE_BY_NAME_AND_TYPE_ERROR(10059,"verify resource by name and type error"),
VIEW_RESOURCE_FILE_ON_LINE_ERROR(10060,"view resource file online error"),
CREATE_RESOURCE_FILE_ON_LINE_ERROR(10061,"create resource file online error"),
RESOURCE_FILE_IS_EMPTY(10062,"resource file is empty"),
EDIT_RESOURCE_FILE_ON_LINE_ERROR(10063,"edit resource file online error"),
DOWNLOAD_RESOURCE_FILE_ERROR(10064,"download resource file error"),
CREATE_UDF_FUNCTION_ERROR(10065 ,"create udf function error"),
VIEW_UDF_FUNCTION_ERROR( 10066,"view udf function error"),
UPDATE_UDF_FUNCTION_ERROR(10067,"updateProcessInstance udf function error"),
QUERY_UDF_FUNCTION_LIST_PAGING_ERROR( 10068,"query udf function list paging error"),
QUERY_DATASOURCE_BY_TYPE_ERROR( 10069,"query datasource by type error"),
VERIFY_UDF_FUNCTION_NAME_ERROR( 10070,"verify udf function name error"),
DELETE_UDF_FUNCTION_ERROR( 10071,"delete udf function error"),
AUTHORIZED_FILE_RESOURCE_ERROR( 10072,"authorized file resource error"),
UNAUTHORIZED_FILE_RESOURCE_ERROR( 10073,"unauthorized file resource error"),
UNAUTHORIZED_UDF_FUNCTION_ERROR( 10074,"unauthorized udf function error"),
AUTHORIZED_UDF_FUNCTION_ERROR(10075,"authorized udf function error"),
CREATE_SCHEDULE_ERROR(10076,"create schedule error"),
UPDATE_SCHEDULE_ERROR(10077,"updateProcessInstance schedule error"),
PUBLISH_SCHEDULE_ONLINE_ERROR(10078,"publish schedule online error"),
OFFLINE_SCHEDULE_ERROR(10079,"offline schedule error"),
QUERY_SCHEDULE_LIST_PAGING_ERROR(10080,"query schedule list paging error"),
QUERY_SCHEDULE_LIST_ERROR(10081,"query schedule list error"),
QUERY_TASK_LIST_PAGING_ERROR(10082,"query task list paging error"),
QUERY_TASK_RECORD_LIST_PAGING_ERROR(10083,"query task record list paging error"),
CREATE_TENANT_ERROR(10084,"create tenant error"),
QUERY_TENANT_LIST_PAGING_ERROR(10085,"query tenant list paging error"),
QUERY_TENANT_LIST_ERROR(10086,"query tenant list error"),
UPDATE_TENANT_ERROR(10087,"updateProcessInstance tenant error"),
DELETE_TENANT_BY_ID_ERROR(10088,"delete tenant by id error"),
VERIFY_TENANT_CODE_ERROR(10089,"verify tenant code error"),
CREATE_USER_ERROR(10090,"create user error"),
QUERY_USER_LIST_PAGING_ERROR(10091,"query user list paging error"),
UPDATE_USER_ERROR(10092,"updateProcessInstance user error"),
DELETE_USER_BY_ID_ERROR(10093,"delete user by id error"),
GRANT_PROJECT_ERROR(10094,"grant project error"),
GRANT_RESOURCE_ERROR(10095,"grant resource error"),
GRANT_UDF_FUNCTION_ERROR(10096,"grant udf function error"),
GRANT_DATASOURCE_ERROR(10097,"grant datasource error"),
GET_USER_INFO_ERROR(10098,"get user info error"),
USER_LIST_ERROR(10099,"user list error"),
VERIFY_USERNAME_ERROR(10100,"verify username error"),
UNAUTHORIZED_USER_ERROR(10101,"unauthorized user error"),
AUTHORIZED_USER_ERROR(10102,"authorized user error"),
QUERY_TASK_INSTANCE_LOG_ERROR(10103,"view task instance log error"),
DOWNLOAD_TASK_INSTANCE_LOG_FILE_ERROR(10104,"download task instance log file error"),
CREATE_PROCESS_DEFINITION(10105,"create process definition"),
VERIFY_PROCESS_DEFINITION_NAME_UNIQUE_ERROR(10106,"verify process definition name unique error"),
UPDATE_PROCESS_DEFINITION_ERROR(10107,"updateProcessInstance process definition error"),
RELEASE_PROCESS_DEFINITION_ERROR(10108,"release process definition error"),
QUERY_DATAIL_OF_PROCESS_DEFINITION_ERROR(10109,"query datail of process definition error"),
QUERY_PROCCESS_DEFINITION_LIST(10110,"query proccess definition list"),
ENCAPSULATION_TREEVIEW_STRUCTURE_ERROR(10111,"encapsulation treeview structure error"),
GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR(10112,"get tasks list by process definition id error"),
QUERY_PROCESS_INSTANCE_LIST_PAGING_ERROR(10113,"query process instance list paging error"),
QUERY_TASK_LIST_BY_PROCESS_INSTANCE_ID_ERROR(10114,"query task list by process instance id error"),
UPDATE_PROCESS_INSTANCE_ERROR(10115,"updateProcessInstance process instance error"),
QUERY_PROCESS_INSTANCE_BY_ID_ERROR(10116,"query process instance by id error"),
DELETE_PROCESS_INSTANCE_BY_ID_ERROR(10117,"delete process instance by id error"),
QUERY_SUB_PROCESS_INSTANCE_DETAIL_INFO_BY_TASK_ID_ERROR(10118,"query sub process instance detail info by task id error"),
QUERY_PARENT_PROCESS_INSTANCE_DETAIL_INFO_BY_SUB_PROCESS_INSTANCE_ID_ERROR(10119,"query parent process instance detail info by sub process instance id error"),
QUERY_PROCESS_INSTANCE_ALL_VARIABLES_ERROR(10120,"query process instance all variables error"),
ENCAPSULATION_PROCESS_INSTANCE_GANTT_STRUCTURE_ERROR(10121,"encapsulation process instance gantt structure error"),
QUERY_PROCCESS_DEFINITION_LIST_PAGING_ERROR(10122,"query proccess definition list paging error"),
SIGN_OUT_ERROR(10123,"sign out error"),
TENANT_CODE_HAS_ALREADY_EXISTS(10124,"tenant code has already exists"),
IP_IS_EMPTY(10125,"ip is empty"),
SCHEDULE_CRON_REALEASE_NEED_NOT_CHANGE(10126, "schedule release is already {0}"),
CREATE_QUEUE_ERROR(10127, "create queue error"),
QUEUE_NOT_EXIST(10128, "queue {0} not exists"),
QUEUE_VALUE_EXIST(10129, "queue value {0} already exists"),
QUEUE_NAME_EXIST(10130, "queue name {0} already exists"),
UPDATE_QUEUE_ERROR(10131, "update queue error"),
NEED_NOT_UPDATE_QUEUE(10132, "no content changes, no updates are required"),
VERIFY_QUEUE_ERROR(10133,"verify queue error"),
NAME_NULL(10134,"name must be not null"),
NAME_EXIST(10135, "name {0} already exists"),
SAVE_ERROR(10136, "save error"),
DELETE_PROJECT_ERROR_DEFINES_NOT_NULL(10137, "please delete the process definitions in project first!"),
BATCH_DELETE_PROCESS_INSTANCE_BY_IDS_ERROR(10117,"batch delete process instance by ids {0} error"),
PREVIEW_SCHEDULE_ERROR(10139,"preview schedule error"),
PARSE_TO_CRON_EXPRESSION_ERROR(10140,"parse cron to cron expression error"),
SCHEDULE_START_TIME_END_TIME_SAME(10141,"The start time must not be the same as the end"),
UDF_FUNCTION_NOT_EXIST(20001, "UDF function not found"),
UDF_FUNCTION_EXISTS(20002, "UDF function already exists"),
// RESOURCE_EMPTY(20003, "resource file is empty"),
RESOURCE_NOT_EXIST(20004, "resource not exist"),
RESOURCE_EXIST(20005, "resource already exists"),
RESOURCE_SUFFIX_NOT_SUPPORT_VIEW(20006, "resource suffix do not support online viewing"),
RESOURCE_SIZE_EXCEED_LIMIT(20007, "upload resource file size exceeds limit"),
RESOURCE_SUFFIX_FORBID_CHANGE(20008, "resource suffix not allowed to be modified"),
UDF_RESOURCE_SUFFIX_NOT_JAR(20009, "UDF resource suffix name must be jar"),
HDFS_COPY_FAIL(20009, "hdfs copy {0} -> {1} fail"),
RESOURCE_FILE_EXIST(20010, "resource file {0} already exists in hdfs,please delete it or change name!"),
RESOURCE_FILE_NOT_EXIST(20011, "resource file {0} not exists in hdfs!"),
USER_NO_OPERATION_PERM(30001, "user has no operation privilege"),
USER_NO_OPERATION_PROJECT_PERM(30002, "user {0} is not has project {1} permission"),
PROCESS_INSTANCE_NOT_EXIST(50001, "process instance {0} does not exist"),
PROCESS_INSTANCE_EXIST(50002, "process instance {0} already exists"),
PROCESS_DEFINE_NOT_EXIST(50003, "process definition {0} does not exist"),
PROCESS_DEFINE_NOT_RELEASE(50004, "process definition {0} not on line"),
PROCESS_INSTANCE_ALREADY_CHANGED(50005, "the status of process instance {0} is already {1}"),
PROCESS_INSTANCE_STATE_OPERATION_ERROR(50006, "the status of process instance {0} is {1},Cannot perform {2} operation"),
SUB_PROCESS_INSTANCE_NOT_EXIST(50007, "the task belong to process instance does not exist"),
PROCESS_DEFINE_NOT_ALLOWED_EDIT(50008, "process definition {0} does not allow edit"),
PROCESS_INSTANCE_EXECUTING_COMMAND(50009, "process instance {0} is executing the command, please wait ..."),
PROCESS_INSTANCE_NOT_SUB_PROCESS_INSTANCE(50010, "process instance {0} is not sub process instance"),
TASK_INSTANCE_STATE_COUNT_ERROR(50011,"task instance state count error"),
COUNT_PROCESS_INSTANCE_STATE_ERROR(50012,"count process instance state error"),
COUNT_PROCESS_DEFINITION_USER_ERROR(50013,"count process definition user error"),
START_PROCESS_INSTANCE_ERROR(50014,"start process instance error"),
EXECUTE_PROCESS_INSTANCE_ERROR(50015,"execute process instance error"),
CHECK_PROCESS_DEFINITION_ERROR(50016,"check process definition error"),
QUERY_RECIPIENTS_AND_COPYERS_BY_PROCESS_DEFINITION_ERROR(50017,"query recipients and copyers by process definition error"),
DATA_IS_NOT_VALID(50017,"data %s not valid"),
DATA_IS_NULL(50018,"data %s is null"),
PROCESS_NODE_HAS_CYCLE(50019,"process node has cycle"),
PROCESS_NODE_S_PARAMETER_INVALID(50020,"process node %s parameter invalid"),
PROCESS_DEFINE_STATE_ONLINE(50021, "process definition {0} is already on line"),
DELETE_PROCESS_DEFINE_BY_ID_ERROR(50022,"delete process definition by id error"),
SCHEDULE_CRON_STATE_ONLINE(50023,"the status of schedule {0} is already on line"),
DELETE_SCHEDULE_CRON_BY_ID_ERROR(50024,"delete schedule by id error"),
BATCH_DELETE_PROCESS_DEFINE_ERROR(50025,"batch delete process definition error"),
BATCH_DELETE_PROCESS_DEFINE_BY_IDS_ERROR(50026,"batch delete process definition by ids {0} error"),
TENANT_NOT_SUITABLE(50027,"there is not any tenant suitable, please choose a tenant available."),
EXPORT_PROCESS_DEFINE_BY_ID_ERROR(50028,"export process definition by id error"),
IMPORT_PROCESS_DEFINE_ERROR(50029,"import process definition error"),
HDFS_NOT_STARTUP(60001,"hdfs not startup"),
HDFS_TERANT_RESOURCES_FILE_EXISTS(60002,"resource file exists,please delete resource first"),
HDFS_TERANT_UDFS_FILE_EXISTS(60003,"udf file exists,please delete resource first"),
/**
* for monitor
*/
QUERY_DATABASE_STATE_ERROR(70001,"query database state error"),
QUERY_ZOOKEEPER_STATE_ERROR(70002,"query zookeeper state error"),
CREATE_ACCESS_TOKEN_ERROR(70001,"create access token error"),
GENERATE_TOKEN_ERROR(70002,"generate token error"),
QUERY_ACCESSTOKEN_LIST_PAGING_ERROR(70003,"query access token list paging error"),
COMMAND_STATE_COUNT_ERROR(80001,"task instance state count error"),
QUEUE_COUNT_ERROR(90001,"queue count error"),
KERBEROS_STARTUP_STATE(100001,"get kerberos startup state error"),
;
private int code;
private String msg;
private Status(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return this.code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return this.msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

29
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/DruidStatFilter.java

@ -0,0 +1,29 @@
/*
* 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.interceptor;
import com.alibaba.druid.support.http.WebStatFilter;
/* this class annotation for druid stat monitor in development
@WebFilter(filterName="druidWebStatFilter",urlPatterns="/*",
initParams={
@WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")
}) */
public class DruidStatFilter extends WebStatFilter {
}

34
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/DruidStatViewServlet.java

@ -0,0 +1,34 @@
/*
* 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.interceptor;
import com.alibaba.druid.support.http.StatViewServlet;
/* this class annotation for druid stat monitor in development
@WebServlet(urlPatterns = "/druid/*",
initParams={
// @WebInitParam(name="allow",value="127.0.0.1"),
// @WebInitParam(name="deny",value="192.168.16.111"),
@WebInitParam(name="loginUsername",value="admin"),
@WebInitParam(name="loginPassword",value="escheduler123"),
@WebInitParam(name="resetEnable",value="true")
}) */
public class DruidStatViewServlet extends StatViewServlet {
}

111
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LoginHandlerInterceptor.java

@ -0,0 +1,111 @@
/*
* 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.interceptor;
import org.apache.dolphinscheduler.api.service.SessionService;
import org.apache.dolphinscheduler.api.utils.Constants;
import org.apache.dolphinscheduler.dao.entity.Session;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.UserMapper;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* login interceptor, must login first
*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LoginHandlerInterceptor.class);
@Autowired
private SessionService sessionService;
@Autowired
private UserMapper userMapper;
/**
* Intercept the execution of a handler. Called after HandlerMapping determined
* an appropriate handler object, but before HandlerAdapter invokes the handler.
* <p>DispatcherServlet processes a handler in an execution chain, consisting
* of any number of interceptors, with the handler itself at the end.
* With this method, each interceptor can decide to abort the execution chain,
* typically sending a HTTP error or writing a custom response.
* <p><strong>Note:</strong> special considerations apply for asynchronous
* request processing. For more details see
* {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
* @param request current HTTP request
* @param response current HTTP response
* @param handler chosen handler to execute, for type and/or instance evaluation
* @return {@code true} if the execution chain should proceed with the
* next interceptor or the handler itself. Else, DispatcherServlet assumes
* that this interceptor has already dealt with the response itself.
* @throws Exception in case of errors
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// get token
String token = request.getHeader("token");
User user = null;
if (StringUtils.isEmpty(token)){
Session session = sessionService.getSession(request);
if (session == null) {
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
logger.info("session info is null ");
return false;
}
//get user object from session
user = userMapper.selectById(session.getUserId());
// if user is null
if (user == null) {
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
logger.info("user does not exist");
return false;
}
}else {
user = userMapper.queryUserByToken(token);
if (user == null) {
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
logger.info("user token has expired");
return false;
}
}
request.setAttribute(Constants.SESSION_USER, user);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}

134
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/log/LogClient.java

@ -0,0 +1,134 @@
/*
* 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.log;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import org.apache.dolphinscheduler.rpc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
/**
* log client
*/
public class LogClient {
private static final Logger logger = LoggerFactory.getLogger(LogClient.class);
private final ManagedChannel channel;
private final LogViewServiceGrpc.LogViewServiceBlockingStub blockingStub;
/**
* construct client connecting to HelloWorld server at {@code host:port}
*/
public LogClient(String host, int port) {
this(ManagedChannelBuilder.forAddress(host, port)
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
// needing certificates.
.usePlaintext(true));
}
/**
* construct client for accessing RouteGuide server using the existing channel
*
*/
LogClient(ManagedChannelBuilder<?> channelBuilder) {
/**
* set max read size
*/
channelBuilder.maxInboundMessageSize(Integer.MAX_VALUE);
channel = channelBuilder.build();
blockingStub = LogViewServiceGrpc.newBlockingStub(channel);
}
/**
* shutdown
*
* @throws InterruptedException
*/
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
/**
* roll view log
*
* @param path
* @param skipLineNum
* @param limit
* @return
*/
public String rollViewLog(String path,int skipLineNum,int limit) {
logger.info("roll view log : path {},skipLineNum {} ,limit {}", path, skipLineNum, limit);
LogParameter pathParameter = LogParameter
.newBuilder()
.setPath(path)
.setSkipLineNum(skipLineNum)
.setLimit(limit)
.build();
RetStrInfo retStrInfo;
try {
retStrInfo = blockingStub.rollViewLog(pathParameter);
return retStrInfo.getMsg();
} catch (StatusRuntimeException e) {
logger.error("roll view log error", e);
return null;
}
}
/**
* view log
*
* @param path
* @return
*/
public String viewLog(String path) {
logger.info("view log path {}",path);
PathParameter pathParameter = PathParameter.newBuilder().setPath(path).build();
RetStrInfo retStrInfo;
try {
retStrInfo = blockingStub.viewLog(pathParameter);
return retStrInfo.getMsg();
} catch (StatusRuntimeException e) {
logger.error("view log error", e);
return null;
}
}
/**
* get log size
*
* @param path
* @return
*/
public byte[] getLogBytes(String path) {
logger.info("log path {}",path);
PathParameter pathParameter = PathParameter.newBuilder().setPath(path).build();
RetByteInfo retByteInfo;
try {
retByteInfo = blockingStub.getLogBytes(pathParameter);
return retByteInfo.getData().toByteArray();
} catch (StatusRuntimeException e) {
logger.error("log size error", e);
return null;
}
}
}

181
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AccessTokenService.java

@ -0,0 +1,181 @@
/*
* 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.service;
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.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.AccessToken;
import org.apache.dolphinscheduler.dao.entity.User;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.common.utils.EncryptionUtils;
import org.apache.dolphinscheduler.dao.mapper.AccessTokenMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* user service
*/
@Service
public class AccessTokenService extends BaseService {
private static final Logger logger = LoggerFactory.getLogger(AccessTokenService.class);
@Autowired
private AccessTokenMapper accessTokenMapper;
/**
* query access token list
*
* @param loginUser
* @param searchVal
* @param pageNo
* @param pageSize
* @return
*/
public Map<String, Object> queryAccessTokenList(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(5);
PageInfo<AccessToken> pageInfo = new PageInfo<>(pageNo, pageSize);
Page<AccessToken> page = new Page(pageNo, pageSize);
int userId = loginUser.getId();
if (loginUser.getUserType() == UserType.ADMIN_USER){
userId = 0;
}
IPage<AccessToken> accessTokenList = accessTokenMapper.selectAccessTokenPage(page, searchVal, userId);
pageInfo.setTotalCount((int)accessTokenList.getTotal());
pageInfo.setLists(accessTokenList.getRecords());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* check
*
* @param result
* @param bool
* @param userNoOperationPerm
* @param status
* @return
*/
private boolean check(Map<String, Object> result, boolean bool, Status userNoOperationPerm, String status) {
//only admin can operate
if (bool) {
result.put(Constants.STATUS, userNoOperationPerm);
result.put(status, userNoOperationPerm.getMsg());
return true;
}
return false;
}
/**
* create token
*
* @param userId
* @param expireTime
* @param token
* @return
*/
public Map<String, Object> createToken(int userId, String expireTime, String token) {
Map<String, Object> result = new HashMap<>(5);
AccessToken accessToken = new AccessToken();
accessToken.setUserId(userId);
accessToken.setExpireTime(DateUtils.stringToDate(expireTime));
accessToken.setToken(token);
accessToken.setCreateTime(new Date());
accessToken.setUpdateTime(new Date());
// insert
int insert = accessTokenMapper.insert(accessToken);
if (insert > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.CREATE_ALERT_GROUP_ERROR);
}
return result;
}
/**
* generate token
* @param userId
* @param expireTime
* @return
*/
public Map<String, Object> generateToken(int userId, String expireTime) {
Map<String, Object> result = new HashMap<>(5);
String token = EncryptionUtils.getMd5(userId + expireTime + String.valueOf(System.currentTimeMillis()));
result.put(Constants.DATA_LIST, token);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* delete access token
* @param loginUser
* @param id
* @return
*/
public Map<String, Object> delAccessTokenById(User loginUser, int id) {
Map<String, Object> result = new HashMap<>(5);
//only admin can operate
if (!isAdmin(loginUser)) {
putMsg(result, Status.USER_NOT_EXIST, id);
return result;
}
accessTokenMapper.deleteById(id);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* update token by id
* @param id
* @param userId
* @param expireTime
* @param token
* @return
*/
public Map<String, Object> updateToken(int id,int userId, String expireTime, String token) {
Map<String, Object> result = new HashMap<>(5);
AccessToken accessToken = new AccessToken();
accessToken.setId(id);
accessToken.setUserId(userId);
accessToken.setExpireTime(DateUtils.stringToDate(expireTime));
accessToken.setToken(token);
accessToken.setUpdateTime(new Date());
accessTokenMapper.updateById(accessToken);
putMsg(result, Status.SUCCESS);
return result;
}
}

294
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AlertGroupService.java

@ -0,0 +1,294 @@
/*
* 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.service;
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.common.enums.AlertType;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.AlertGroup;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.entity.UserAlertGroup;
import org.apache.dolphinscheduler.dao.mapper.AlertGroupMapper;
import org.apache.dolphinscheduler.dao.mapper.UserAlertGroupMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* alert group service
*/
@Service
public class AlertGroupService {
private static final Logger logger = LoggerFactory.getLogger(AlertGroupService.class);
@Autowired
private AlertGroupMapper alertGroupMapper;
@Autowired
private UserAlertGroupMapper userAlertGroupMapper;
/**
* query alert group list
*
* @return
*/
public HashMap<String, Object> queryAlertgroup() {
HashMap<String, Object> result = new HashMap<>(5);
List<AlertGroup> alertGroups = alertGroupMapper.queryAllGroupList();
result.put(Constants.DATA_LIST, alertGroups);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* paging query alarm group list
*
* @param loginUser
* @param searchVal
* @param pageNo
* @param pageSize
* @return
*/
public Map<String, Object> listPaging(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(5);
Page<AlertGroup> page = new Page(pageNo, pageSize);
IPage<AlertGroup> alertGroupIPage = alertGroupMapper.queryAlertGroupPage(
page, searchVal);
PageInfo<AlertGroup> pageInfo = new PageInfo<>(pageNo, pageSize);
pageInfo.setTotalCount((int)alertGroupIPage.getTotal());
pageInfo.setLists(alertGroupIPage.getRecords());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* create alert group
*
* @param loginUser
* @param groupName
* @param groupType
* @param desc
* @return
*/
public Map<String, Object> createAlertgroup(User loginUser, String groupName, AlertType groupType, String desc) {
Map<String, Object> result = new HashMap<>(5);
//only admin can operate
if (checkAdmin(loginUser, result)){
return result;
}
AlertGroup alertGroup = new AlertGroup();
Date now = new Date();
alertGroup.setGroupName(groupName);
alertGroup.setGroupType(groupType);
alertGroup.setDescription(desc);
alertGroup.setCreateTime(now);
alertGroup.setUpdateTime(now);
// insert
int insert = alertGroupMapper.insert(alertGroup);
if (insert > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.CREATE_ALERT_GROUP_ERROR);
}
return result;
}
/**
* check user is admin or not
*
* @param user
* @return
*/
public boolean isAdmin(User user) {
return user.getUserType() == UserType.ADMIN_USER;
}
/**
* updateProcessInstance alert group
*
* @param loginUser
* @param id
* @param groupName
* @param groupType
* @param desc
* @return
*/
public Map<String, Object> updateAlertgroup(User loginUser, int id, String groupName, AlertType groupType, String desc) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)){
return result;
}
AlertGroup alertGroup = alertGroupMapper.selectById(id);
if (alertGroup == null) {
putMsg(result, Status.ALERT_GROUP_NOT_EXIST);
return result;
}
Date now = new Date();
if (StringUtils.isNotEmpty(groupName)) {
alertGroup.setGroupName(groupName);
}
if (groupType != null) {
alertGroup.setGroupType(groupType);
}
alertGroup.setDescription(desc);
alertGroup.setUpdateTime(now);
// updateProcessInstance
alertGroupMapper.updateById(alertGroup);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* delete alert group by id
*
* @param loginUser
* @param id
* @return
*/
public Map<String, Object> delAlertgroupById(User loginUser, int id) {
Map<String, Object> result = new HashMap<>(5);
result.put(Constants.STATUS, false);
//only admin can operate
if (checkAdmin(loginUser, result)){
return result;
}
alertGroupMapper.deleteById(id);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* grant user
*
* @param loginUser
* @param alertgroupId
* @param userIds
* @return
*/
public Map<String, Object> grantUser(User loginUser, int alertgroupId, String userIds) {
Map<String, Object> result = new HashMap<>(5);
result.put(Constants.STATUS, false);
//only admin can operate
if (checkAdmin(loginUser, result)){
return result;
}
userAlertGroupMapper.deleteByAlertgroupId(alertgroupId);
if (StringUtils.isEmpty(userIds)) {
putMsg(result, Status.SUCCESS);
return result;
}
String[] userIdsArr = userIds.split(",");
for (String userId : userIdsArr) {
Date now = new Date();
UserAlertGroup userAlertGroup = new UserAlertGroup();
userAlertGroup.setAlertgroupId(alertgroupId);
userAlertGroup.setUserId(Integer.parseInt(userId));
userAlertGroup.setCreateTime(now);
userAlertGroup.setUpdateTime(now);
userAlertGroupMapper.insert(userAlertGroup);
}
putMsg(result, Status.SUCCESS);
return result;
}
/**
* verify group name exists
*
* @param loginUser
* @param groupName
* @return
*/
public Result verifyGroupName(User loginUser, String groupName) {
Result result = new Result();
List<AlertGroup> alertGroup = alertGroupMapper.queryByGroupName(groupName);
if (alertGroup != null && alertGroup.size() > 0) {
logger.error("group {} has exist, can't create again.", groupName);
result.setCode(Status.ALERT_GROUP_EXIST.getCode());
result.setMsg(Status.ALERT_GROUP_EXIST.getMsg());
} else {
result.setCode(Status.SUCCESS.getCode());
result.setMsg(Status.SUCCESS.getMsg());
}
return result;
}
/**
* is admin?
* @param loginUser
* @param result
* @return
*/
private boolean checkAdmin(User loginUser, Map<String, Object> result) {
if (!isAdmin(loginUser)) {
putMsg(result, Status.USER_NO_OPERATION_PERM);
return true;
}
return false;
}
/**
* put message
*
* @param result
* @param status
*/
private void putMsg(Map<String, Object> result, Status status) {
result.put(Constants.STATUS, status);
result.put(Constants.MSG, status.getMsg());
}
}

89
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/BaseDAGService.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.api.service;
import org.apache.dolphinscheduler.common.graph.DAG;
import org.apache.dolphinscheduler.common.model.TaskNode;
import org.apache.dolphinscheduler.common.model.TaskNodeRelation;
import org.apache.dolphinscheduler.common.process.ProcessDag;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.dao.entity.ProcessData;
import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
import java.util.ArrayList;
import java.util.List;
/**
* base DAG service
*/
public class BaseDAGService extends BaseService{
/**
* process instance to DAG
*
* @param processInstance
* @return
* @throws Exception
*/
public static DAG<String, TaskNode, TaskNodeRelation> processInstance2DAG(ProcessInstance processInstance) throws Exception {
String processDefinitionJson = processInstance.getProcessInstanceJson();
ProcessData processData = JSONUtils.parseObject(processDefinitionJson, ProcessData.class);
List<TaskNode> taskNodeList = processData.getTasks();
List<TaskNodeRelation> taskNodeRelations = new ArrayList<>();
//Traversing node information and building relationships
for (TaskNode taskNode : taskNodeList) {
String preTasks = taskNode.getPreTasks();
List<String> preTasksList = JSONUtils.toList(preTasks, String.class);
//if previous tasks not empty
if (preTasksList != null) {
for (String depNode : preTasksList) {
taskNodeRelations.add(new TaskNodeRelation(depNode, taskNode.getName()));
}
}
}
ProcessDag processDag = new ProcessDag();
processDag.setEdges(taskNodeRelations);
processDag.setNodes(taskNodeList);
// generate detail Dag, to be executed
DAG<String, TaskNode, TaskNodeRelation> dag = new DAG<>();
if (CollectionUtils.isNotEmpty(processDag.getNodes())) {
for (TaskNode node : processDag.getNodes()) {
dag.addNode(node.getName(), node);
}
}
if (CollectionUtils.isNotEmpty(processDag.getEdges())) {
for (TaskNodeRelation edge : processDag.getEdges()) {
dag.addEdge(edge.getStartNode(), edge.getEndNode());
}
}
return dag;
}
}

130
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/BaseService.java

@ -0,0 +1,130 @@
/*
* 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.service;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Constants;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.common.utils.HadoopUtils;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.text.MessageFormat;
import java.util.Map;
/**
* base service
*/
public class BaseService {
/**
* check admin
*
* @param user
* @return
*/
protected boolean isAdmin(User user) {
return user.getUserType() == UserType.ADMIN_USER;
}
/**
* check admin
*
* @param loginUser
* @param result
* @return
*/
protected boolean checkAdmin(User loginUser, Map<String, Object> result) {
//only admin can operate
if (!isAdmin(loginUser)) {
putMsg(result, Status.USER_NO_OPERATION_PERM);
return true;
}
return false;
}
/**
* put message to map
*
* @param result
* @param status
* @param statusParams
*/
protected void putMsg(Map<String, Object> 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 cookie info by name
* @param request
* @param name
* @return get cookie info
*/
public static Cookie getCookie(HttpServletRequest request, String name) {
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
if (StringUtils.equalsIgnoreCase(name, cookie.getName())) {
return cookie;
}
}
}
return null;
}
/**
* create tenant dir if not exists
* @param tenantCode
* @throws Exception
*/
protected void createTenantDirIfNotExists(String tenantCode)throws Exception{
String resourcePath = HadoopUtils.getHdfsResDir(tenantCode);
String udfsPath = HadoopUtils.getHdfsUdfDir(tenantCode);
/**
* init resource path and udf path
*/
HadoopUtils.getInstance().mkdir(resourcePath);
HadoopUtils.getInstance().mkdir(udfsPath);
}
}

416
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/DataAnalysisService.java

@ -0,0 +1,416 @@
/*
* 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.service;
import org.apache.dolphinscheduler.api.dto.CommandStateCount;
import org.apache.dolphinscheduler.api.dto.DefineUserDto;
import org.apache.dolphinscheduler.api.dto.TaskCountDto;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Constants;
import org.apache.dolphinscheduler.common.enums.CommandType;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.common.queue.ITaskQueue;
import org.apache.dolphinscheduler.common.queue.TaskQueueFactory;
import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.dao.ProcessDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.dolphinscheduler.dao.entity.*;
import org.apache.dolphinscheduler.dao.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.MessageFormat;
import java.util.*;
/**
* data analysis service
*/
@Service
public class DataAnalysisService {
private static final Logger logger = LoggerFactory.getLogger(DataAnalysisService.class);
@Autowired
ProjectMapper projectMapper;
@Autowired
ProjectService projectService;
@Autowired
ProcessInstanceMapper processInstanceMapper;
@Autowired
ProcessDefinitionMapper processDefinitionMapper;
@Autowired
CommandMapper commandMapper;
@Autowired
ErrorCommandMapper errorCommandMapper;
@Autowired
TaskInstanceMapper taskInstanceMapper;
@Autowired
ProcessDao processDao;
/**
* statistical task instance status data
*
* @param loginUser
* @param projectId
* @param startDate
* @param endDate
* @return
*/
public Map<String,Object> countTaskStateByProject(User loginUser, int projectId, String startDate, String endDate) {
Map<String, Object> result = new HashMap<>(5);
if(projectId != 0){
Project project = projectMapper.selectById(projectId);
result = projectService.checkProjectAndAuth(loginUser, project, String.valueOf(projectId));
if (getResultStatus(result)){
return result;
}
}
/**
* find all the task lists in the project under the user
* statistics based on task status execution, failure, completion, wait, total
*/
Date start = null;
Date end = null;
try {
start = DateUtils.getScheduleDate(startDate);
end = DateUtils.getScheduleDate(endDate);
} catch (Exception e) {
logger.error(e.getMessage(),e);
putErrorRequestParamsMsg(result);
return result;
}
List<ExecuteStatusCount> taskInstanceStateCounts =
taskInstanceMapper.countTaskInstanceStateByUser(loginUser.getId(),
loginUser.getUserType(), start, end, String.valueOf(projectId));
TaskCountDto taskCountResult = new TaskCountDto(taskInstanceStateCounts);
if (taskInstanceStateCounts != null) {
result.put(Constants.DATA_LIST, taskCountResult);
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.TASK_INSTANCE_STATE_COUNT_ERROR);
}
return result;
}
private void putErrorRequestParamsMsg(Map<String, Object> result) {
result.put(Constants.STATUS, Status.REQUEST_PARAMS_NOT_VALID_ERROR);
result.put(Constants.MSG, MessageFormat.format(Status.REQUEST_PARAMS_NOT_VALID_ERROR.getMsg(), "startDate,endDate"));
}
/**
* statistical process instance status data
*
* @param loginUser
* @param projectId
* @param startDate
* @param endDate
* @return
*/
public Map<String,Object> countProcessInstanceStateByProject(User loginUser, int projectId, String startDate, String endDate) {
Map<String, Object> result = new HashMap<>(5);
if(projectId != 0){
Project project = projectMapper.selectById(projectId);
result = projectService.checkProjectAndAuth(loginUser, project, String.valueOf(projectId));
if (getResultStatus(result)){
return result;
}
}
Date start = null;
Date end = null;
try {
start = DateUtils.getScheduleDate(startDate);
end = DateUtils.getScheduleDate(endDate);
} catch (Exception e) {
logger.error(e.getMessage(),e);
putErrorRequestParamsMsg(result);
return result;
}
List<Integer> projectIds = new ArrayList<>();
if(projectId !=0){
projectIds.add(projectId);
}else if(loginUser.getUserType() == UserType.GENERAL_USER){
projectIds = processDao.getProjectIdListHavePerm(loginUser.getId());
}
Integer[] projectIdArray = projectIds.toArray(new Integer[projectIds.size()]);
List<ExecuteStatusCount> processInstanceStateCounts =
processInstanceMapper.countInstanceStateByUser(start, end,
projectIdArray);
TaskCountDto taskCountResult = new TaskCountDto(processInstanceStateCounts);
if (processInstanceStateCounts != null) {
result.put(Constants.DATA_LIST, taskCountResult);
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.COUNT_PROCESS_INSTANCE_STATE_ERROR);
}
return result;
}
/**
* statistics the process definition quantities of certain person
*
* @param loginUser
* @param projectId
* @return
*/
public Map<String,Object> countDefinitionByUser(User loginUser, int projectId) {
Map<String, Object> result = new HashMap<>();
Integer[] projectIdArray = new Integer[1];
projectIdArray[0] = projectId;
List<DefinitionGroupByUser> defineGroupByUsers = processDefinitionMapper.countDefinitionGroupByUser(
loginUser.getId(), projectIdArray);
DefineUserDto dto = new DefineUserDto(defineGroupByUsers);
result.put(Constants.DATA_LIST, dto);
putMsg(result, Status.SUCCESS);
return result;
}
/**
*
* @param result
* @param status
*/
private void putMsg(Map<String, Object> result, Status status) {
result.put(Constants.STATUS, status);
result.put(Constants.MSG, status.getMsg());
}
/**
* get result status
* @param result
* @return
*/
private boolean getResultStatus(Map<String, Object> result) {
Status resultEnum = (Status) result.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return true;
}
return false;
}
/**
* statistical command status data
*
* @param loginUser
* @param projectId
* @param startDate
* @param endDate
* @return
*/
public Map<String, Object> countCommandState(User loginUser, int projectId, String startDate, String endDate) {
Map<String, Object> result = new HashMap<>(5);
if(projectId != 0){
Project project = projectMapper.selectById(projectId);
result = projectService.checkProjectAndAuth(loginUser, project, String.valueOf(projectId));
if (getResultStatus(result)){
return result;
}
}
/**
* find all the task lists in the project under the user
* statistics based on task status execution, failure, completion, wait, total
*/
Date start = null;
Date end = null;
try {
start = DateUtils.getScheduleDate(startDate);
end = DateUtils.getScheduleDate(endDate);
} catch (Exception e) {
logger.error(e.getMessage(),e);
putErrorRequestParamsMsg(result);
return result;
}
List<Integer> projectIds = new ArrayList<>();
if(projectId !=0){
projectIds.add(projectId);
}else if(loginUser.getUserType() == UserType.GENERAL_USER){
projectIds = processDao.getProjectIdListHavePerm(loginUser.getId());
}
Integer[] projectIdArray = projectIds.toArray(new Integer[projectIds.size()]);
// count command state
List<CommandCount> commandStateCounts =
commandMapper.countCommandState(
loginUser.getId(),
start,
end,
projectIdArray);
// count error command state
List<CommandCount> errorCommandStateCounts =
errorCommandMapper.countCommandState(
start, end, projectIdArray);
//
Map<CommandType,Map<String,Integer>> dataMap = new HashMap<>();
Map<String,Integer> commonCommand = new HashMap<>();
commonCommand.put("commandState",0);
commonCommand.put("errorCommandState",0);
// init data map
// dataMap.put(ExecutionStatus.SUBMITTED_SUCCESS,commonCommand);
// dataMap.put(ExecutionStatus.RUNNING_EXEUTION,commonCommand);
// dataMap.put(ExecutionStatus.READY_PAUSE,commonCommand);
// dataMap.put(ExecutionStatus.PAUSE,commonCommand);
// dataMap.put(ExecutionStatus.READY_STOP,commonCommand);
// dataMap.put(ExecutionStatus.STOP,commonCommand);
// dataMap.put(ExecutionStatus.FAILURE,commonCommand);
// dataMap.put(ExecutionStatus.SUCCESS,commonCommand);
// dataMap.put(ExecutionStatus.NEED_FAULT_TOLERANCE,commonCommand);
// dataMap.put(ExecutionStatus.KILL,commonCommand);
// dataMap.put(ExecutionStatus.WAITTING_THREAD,commonCommand);
// dataMap.put(ExecutionStatus.WAITTING_DEPEND,commonCommand);
// put command state
for (CommandCount executeStatusCount : commandStateCounts){
Map<String,Integer> commandStateCountsMap = new HashMap<>(dataMap.get(executeStatusCount.getCommandType()));
commandStateCountsMap.put("commandState", executeStatusCount.getCount());
dataMap.put(executeStatusCount.getCommandType(),commandStateCountsMap);
}
// put error command state
for (CommandCount errorExecutionStatus : errorCommandStateCounts){
Map<String,Integer> errorCommandStateCountsMap = new HashMap<>(dataMap.get(errorExecutionStatus.getCommandType()));
errorCommandStateCountsMap.put("errorCommandState",errorExecutionStatus.getCount());
dataMap.put(errorExecutionStatus.getCommandType(),errorCommandStateCountsMap);
}
List<CommandStateCount> list = new ArrayList<>();
Iterator<Map.Entry<CommandType, Map<String, Integer>>> iterator = dataMap.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<CommandType, Map<String, Integer>> next = iterator.next();
CommandStateCount commandStateCount = new CommandStateCount(next.getValue().get("errorCommandState"),
next.getValue().get("commandState"),next.getKey());
list.add(commandStateCount);
}
result.put(Constants.DATA_LIST, list);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* count queue state
* @param loginUser
* @param projectId
* @return
*/
public Map<String, Object> countQueueState(User loginUser, int projectId) {
Map<String, Object> result = new HashMap<>(5);
if(projectId != 0){
Project project = projectMapper.selectById(projectId);
result = projectService.checkProjectAndAuth(loginUser, project, String.valueOf(projectId));
if (getResultStatus(result)){
return result;
}
}
ITaskQueue tasksQueue = TaskQueueFactory.getTaskQueueInstance();
List<String> tasksQueueList = tasksQueue.getAllTasks(org.apache.dolphinscheduler.common.Constants.SCHEDULER_TASKS_QUEUE);
List<String> tasksKillList = tasksQueue.getAllTasks(org.apache.dolphinscheduler.common.Constants.SCHEDULER_TASKS_KILL);
Map<String,Integer> dataMap = new HashMap<>();
if (loginUser.getUserType() == UserType.ADMIN_USER){
dataMap.put("taskQueue",tasksQueueList.size());
dataMap.put("taskKill",tasksKillList.size());
result.put(Constants.DATA_LIST, dataMap);
putMsg(result, Status.SUCCESS);
return result;
}
int[] tasksQueueIds = new int[tasksQueueList.size()];
int[] tasksKillIds = new int[tasksKillList.size()];
int i =0;
for (String taskQueueStr : tasksQueueList){
if (StringUtils.isNotEmpty(taskQueueStr)){
String[] splits = taskQueueStr.split("_");
if (splits.length == 4){
tasksQueueIds[i++]=Integer.parseInt(splits[3]);
}
}
}
i = 0;
for (String taskKillStr : tasksKillList){
if (StringUtils.isNotEmpty(taskKillStr)){
String[] splits = taskKillStr.split("-");
if (splits.length == 2){
tasksKillIds[i++]=Integer.parseInt(splits[1]);
}
}
}
Integer taskQueueCount = 0;
Integer taskKillCount = 0;
int[] projectIds = new int[1];
projectIds[0] = projectId;
if (tasksQueueIds.length != 0){
taskQueueCount = taskInstanceMapper.countTask(
loginUser.getId(),loginUser.getUserType(),projectIds,
tasksQueueIds);
}
if (tasksKillIds.length != 0){
taskKillCount = taskInstanceMapper.countTask(loginUser.getId(),loginUser.getUserType(), projectIds, tasksKillIds);
}
dataMap.put("taskQueue",taskQueueCount);
dataMap.put("taskKill",taskKillCount);
result.put(Constants.DATA_LIST, dataMap);
putMsg(result, Status.SUCCESS);
return result;
}
}

690
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/DataSourceService.java

@ -0,0 +1,690 @@
/*
* 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.service;
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.common.enums.DbType;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.common.job.db.*;
import org.apache.dolphinscheduler.common.utils.CommonUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.dao.entity.DataSource;
import org.apache.dolphinscheduler.dao.entity.Resource;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.DataSourceMapper;
import org.apache.dolphinscheduler.dao.mapper.DataSourceUserMapper;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.*;
import static org.apache.dolphinscheduler.common.utils.PropertyUtils.getString;
/**
* datasource service
*/
@Service
public class DataSourceService extends BaseService{
private static final Logger logger = LoggerFactory.getLogger(DataSourceService.class);
public static final String NAME = "name";
public static final String NOTE = "note";
public static final String TYPE = "type";
public static final String HOST = "host";
public static final String PORT = "port";
public static final String PRINCIPAL = "principal";
public static final String DATABASE = "database";
public static final String USER_NAME = "userName";
public static final String PASSWORD = org.apache.dolphinscheduler.common.Constants.PASSWORD;
public static final String OTHER = "other";
@Autowired
private DataSourceMapper dataSourceMapper;
@Autowired
private DataSourceUserMapper datasourceUserMapper;
/**
* create data source
*
* @param loginUser
* @param name
* @param desc
* @param type
* @param parameter
* @return
*/
public Map<String, Object> createDataSource(User loginUser, String name, String desc, DbType type, String parameter) {
Map<String, Object> result = new HashMap<>(5);
// check name can use or not
if (checkName(name, result)) {
return result;
}
Boolean isConnection = checkConnection(type, parameter);
if (!isConnection) {
logger.info("connect failed, type:{}, parameter:{}", type, parameter);
putMsg(result, Status.DATASOURCE_CONNECT_FAILED);
return result;
}
BaseDataSource datasource = DataSourceFactory.getDatasource(type, parameter);
if (datasource == null) {
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, parameter);
return result;
}
// build datasource
DataSource dataSource = new DataSource();
Date now = new Date();
dataSource.setName(name.trim());
dataSource.setNote(desc);
dataSource.setUserId(loginUser.getId());
dataSource.setUserName(loginUser.getUserName());
dataSource.setType(type);
dataSource.setConnectionParams(parameter);
dataSource.setCreateTime(now);
dataSource.setUpdateTime(now);
dataSourceMapper.insert(dataSource);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* updateProcessInstance datasource
*
* @param loginUser
* @param name
* @param desc
* @param type
* @param parameter
* @return
*/
public Map<String, Object> updateDataSource(int id, User loginUser, String name, String desc, DbType type, String parameter) {
Map<String, Object> result = new HashMap<>();
// determine whether the data source exists
DataSource dataSource = dataSourceMapper.selectById(id);
if (dataSource == null) {
putMsg(result, Status.RESOURCE_NOT_EXIST);
return result;
}
//check name can use or not
if(!name.trim().equals(dataSource.getName()) && checkName(name, result)){
return result;
}
Boolean isConnection = checkConnection(type, parameter);
if (!isConnection) {
logger.info("connect failed, type:{}, parameter:{}", type, parameter);
putMsg(result, Status.DATASOURCE_CONNECT_FAILED);
return result;
}
Date now = new Date();
dataSource.setName(name.trim());
dataSource.setNote(desc);
dataSource.setUserName(loginUser.getUserName());
dataSource.setType(type);
dataSource.setConnectionParams(parameter);
dataSource.setUpdateTime(now);
dataSourceMapper.updateById(dataSource);
putMsg(result, Status.SUCCESS);
return result;
}
private boolean checkName(String name, Map<String, Object> result) {
List<DataSource> queryDataSource = dataSourceMapper.queryDataSourceByName(name.trim());
if (queryDataSource != null && queryDataSource.size() > 0) {
putMsg(result, Status.DATASOURCE_EXIST);
return true;
}
return false;
}
/**
* updateProcessInstance datasource
*/
public Map<String, Object> queryDataSource(int id) {
Map<String, Object> result = new HashMap<String, Object>(5);
DataSource dataSource = dataSourceMapper.selectById(id);
if (dataSource == null) {
putMsg(result, Status.RESOURCE_NOT_EXIST);
return result;
}
// type
String dataSourceType = dataSource.getType().toString();
// name
String dataSourceName = dataSource.getName();
// desc
String desc = dataSource.getNote();
// parameter
String parameter = dataSource.getConnectionParams();
BaseDataSource datasourceForm = DataSourceFactory.getDatasource(dataSource.getType(), parameter);
String database = datasourceForm.getDatabase();
// jdbc connection params
String other = datasourceForm.getOther();
String address = datasourceForm.getAddress();
String[] hostsPorts = getHostsAndPort(address);
// ip host
String host = hostsPorts[0];
// prot
String port = hostsPorts[1];
String separator = "";
switch (dataSource.getType()) {
case HIVE:
case SQLSERVER:
separator = ";";
break;
case MYSQL:
case POSTGRESQL:
case CLICKHOUSE:
case ORACLE:
separator = "&";
break;
default:
separator = "&";
break;
}
Map<String, String> otherMap = new LinkedHashMap<String, String>();
if (other != null) {
String[] configs = other.split(separator);
for (String config : configs) {
otherMap.put(config.split("=")[0], config.split("=")[1]);
}
}
Map<String, Object> map = new HashMap<>(10);
map.put(NAME, dataSourceName);
map.put(NOTE, desc);
map.put(TYPE, dataSourceType);
map.put(HOST, host);
map.put(PORT, port);
map.put(PRINCIPAL, datasourceForm.getPrincipal());
map.put(DATABASE, database);
map.put(USER_NAME, datasourceForm.getUser());
map.put(PASSWORD, datasourceForm.getPassword());
map.put(OTHER, otherMap);
result.put(Constants.DATA_LIST, map);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query datasource list by keyword
*
* @param loginUser
* @param searchVal
* @param pageNo
* @param pageSize
* @return
*/
public Map<String, Object> queryDataSourceListPaging(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>();
IPage<DataSource> dataSourceList = null;
Page<DataSource> dataSourcePage = new Page(pageNo, pageSize);
if (isAdmin(loginUser)) {
dataSourceList = dataSourceMapper.selectPaging(dataSourcePage, 0, searchVal);
}else{
dataSourceList = dataSourceMapper.selectPaging(dataSourcePage, loginUser.getId(), searchVal);
}
List<DataSource> dataSources = dataSourceList.getRecords();
handlePasswd(dataSources);
PageInfo pageInfo = new PageInfo<Resource>(pageNo, pageSize);
pageInfo.setTotalCount((int)(dataSourceList.getTotal()));
pageInfo.setLists(dataSources);
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* get list paging
*
* @param loginUser
* @param searchVal
* @param pageSize
* @param pageInfo
* @return
*/
private List<DataSource> getDataSources(User loginUser, String searchVal, Integer pageSize, PageInfo pageInfo) {
IPage<DataSource> dataSourceList = null;
Page<DataSource> dataSourcePage = new Page(pageInfo.getStart(), pageSize);
if (isAdmin(loginUser)) {
dataSourceList = dataSourceMapper.selectPaging(dataSourcePage, 0, searchVal);
}else{
dataSourceList = dataSourceMapper.selectPaging(dataSourcePage, loginUser.getId(), searchVal);
}
List<DataSource> dataSources = dataSourceList.getRecords();
handlePasswd(dataSources);
return dataSources;
}
/**
* handle datasource connection password for safety
* @param dataSourceList
*/
private void handlePasswd(List<DataSource> dataSourceList) {
for (DataSource dataSource : dataSourceList) {
String connectionParams = dataSource.getConnectionParams();
JSONObject object = JSONObject.parseObject(connectionParams);
object.put(org.apache.dolphinscheduler.common.Constants.PASSWORD, org.apache.dolphinscheduler.common.Constants.XXXXXX);
dataSource.setConnectionParams(JSONUtils.toJson(object));
}
}
/**
* query data resource list
*
* @param loginUser
* @param type
* @return
*/
public Map<String, Object> queryDataSourceList(User loginUser, Integer type) {
Map<String, Object> result = new HashMap<>(5);
List<DataSource> datasourceList;
if (isAdmin(loginUser)) {
datasourceList = dataSourceMapper.listAllDataSourceByType(type);
}else{
datasourceList = dataSourceMapper.queryDataSourceByType(loginUser.getId(), type);
}
result.put(Constants.DATA_LIST, datasourceList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* verify datasource exists
*
* @param loginUser
* @param name
* @return
*/
public Result verifyDataSourceName(User loginUser, String name) {
Result result = new Result();
List<DataSource> dataSourceList = dataSourceMapper.queryDataSourceByName(name);
if (dataSourceList != null && dataSourceList.size() > 0) {
logger.error("datasource name:{} has exist, can't create again.", name);
putMsg(result, Status.DATASOURCE_EXIST);
} else {
putMsg(result, Status.SUCCESS);
}
return result;
}
/**
* get connection
*
* @param dbType
* @param parameter
* @return
*/
private Connection getConnection(DbType dbType, String parameter) {
Connection connection = null;
BaseDataSource datasource = null;
try {
switch (dbType) {
case POSTGRESQL:
datasource = JSONObject.parseObject(parameter, PostgreDataSource.class);
Class.forName(Constants.ORG_POSTGRESQL_DRIVER);
break;
case MYSQL:
datasource = JSONObject.parseObject(parameter, MySQLDataSource.class);
Class.forName(Constants.COM_MYSQL_JDBC_DRIVER);
break;
case HIVE:
case SPARK:
if (CommonUtils.getKerberosStartupState()) {
System.setProperty(org.apache.dolphinscheduler.common.Constants.JAVA_SECURITY_KRB5_CONF,
getString(org.apache.dolphinscheduler.common.Constants.JAVA_SECURITY_KRB5_CONF_PATH));
Configuration configuration = new Configuration();
configuration.set(org.apache.dolphinscheduler.common.Constants.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
UserGroupInformation.setConfiguration(configuration);
UserGroupInformation.loginUserFromKeytab(getString(org.apache.dolphinscheduler.common.Constants.LOGIN_USER_KEY_TAB_USERNAME),
getString(org.apache.dolphinscheduler.common.Constants.LOGIN_USER_KEY_TAB_PATH));
}
if (dbType == DbType.HIVE){
datasource = JSONObject.parseObject(parameter, HiveDataSource.class);
}else if (dbType == DbType.SPARK){
datasource = JSONObject.parseObject(parameter, SparkDataSource.class);
}
Class.forName(Constants.ORG_APACHE_HIVE_JDBC_HIVE_DRIVER);
break;
case CLICKHOUSE:
datasource = JSONObject.parseObject(parameter, ClickHouseDataSource.class);
Class.forName(Constants.COM_CLICKHOUSE_JDBC_DRIVER);
break;
case ORACLE:
datasource = JSONObject.parseObject(parameter, OracleDataSource.class);
Class.forName(Constants.COM_ORACLE_JDBC_DRIVER);
break;
case SQLSERVER:
datasource = JSONObject.parseObject(parameter, SQLServerDataSource.class);
Class.forName(Constants.COM_SQLSERVER_JDBC_DRIVER);
break;
default:
break;
}
if(datasource != null){
connection = DriverManager.getConnection(datasource.getJdbcUrl(), datasource.getUser(), datasource.getPassword());
}
} catch (Exception e) {
logger.error(e.getMessage(),e);
}
return connection;
}
/**
* check connection
*
* @param type
* @param parameter
* @return
*/
public boolean checkConnection(DbType type, String parameter) {
Boolean isConnection = false;
Connection con = getConnection(type, parameter);
if (con != null) {
isConnection = true;
try {
con.close();
} catch (SQLException e) {
logger.error("close connection fail at DataSourceService::checkConnection()", e);
}
}
return isConnection;
}
/**
* test connection
*
* @param loginUser
* @param id
* @return
*/
public boolean connectionTest(User loginUser, int id) {
DataSource dataSource = dataSourceMapper.selectById(id);
return checkConnection(dataSource.getType(), dataSource.getConnectionParams());
}
/**
* build paramters
*
* @param name
* @param desc
* @param type
* @param host
* @param port
* @param database
* @param userName
* @param password
* @param other
* @return
*/
public String buildParameter(String name, String desc, DbType type, String host,
String port, String database,String principal,String userName,
String password, String other) {
String address = buildAddress(type, host, port);
String jdbcUrl = address + "/" + database;
if (CommonUtils.getKerberosStartupState() &&
(type == DbType.HIVE || type == DbType.SPARK)){
jdbcUrl += ";principal=" + principal;
}
String separator = "";
if (Constants.MYSQL.equals(type.name())
|| Constants.POSTGRESQL.equals(type.name())
|| Constants.CLICKHOUSE.equals(type.name())
|| Constants.ORACLE.equals(type.name())) {
separator = "&";
} else if (Constants.HIVE.equals(type.name())
|| Constants.SPARK.equals(type.name())
|| Constants.SQLSERVER.equals(type.name())) {
separator = ";";
}
Map<String, Object> parameterMap = new LinkedHashMap<String, Object>(6);
parameterMap.put(Constants.ADDRESS, address);
parameterMap.put(Constants.DATABASE, database);
parameterMap.put(Constants.JDBC_URL, jdbcUrl);
parameterMap.put(Constants.USER, userName);
parameterMap.put(Constants.PASSWORD, password);
if (CommonUtils.getKerberosStartupState() &&
(type == DbType.HIVE || type == DbType.SPARK)){
parameterMap.put(Constants.PRINCIPAL,principal);
}
if (other != null && !"".equals(other)) {
Map map = JSONObject.parseObject(other, new TypeReference<LinkedHashMap<String, String>>() {
});
if (map.size() > 0) {
Set<String> keys = map.keySet();
StringBuilder otherSb = new StringBuilder();
for (String key : keys) {
otherSb.append(String.format("%s=%s%s", key, map.get(key), separator));
}
otherSb.deleteCharAt(otherSb.length() - 1);
parameterMap.put(Constants.OTHER, otherSb);
}
}
if(logger.isDebugEnabled()){
logger.info("parameters map-----" + JSONObject.toJSONString(parameterMap));
}
return JSONObject.toJSONString(parameterMap);
}
private String buildAddress(DbType type, String host, String port) {
StringBuilder sb = new StringBuilder();
if (Constants.MYSQL.equals(type.name())) {
sb.append(Constants.JDBC_MYSQL);
sb.append(host).append(":").append(port);
} else if (Constants.POSTGRESQL.equals(type.name())) {
sb.append(Constants.JDBC_POSTGRESQL);
sb.append(host).append(":").append(port);
} else if (Constants.HIVE.equals(type.name()) || Constants.SPARK.equals(type.name())) {
sb.append(Constants.JDBC_HIVE_2);
String[] hostArray = host.split(",");
if (hostArray.length > 0) {
for (String zkHost : hostArray) {
sb.append(String.format("%s:%s,", zkHost, port));
}
sb.deleteCharAt(sb.length() - 1);
}
} else if (Constants.CLICKHOUSE.equals(type.name())) {
sb.append(Constants.JDBC_CLICKHOUSE);
sb.append(host).append(":").append(port);
} else if (Constants.ORACLE.equals(type.name())) {
sb.append(Constants.JDBC_ORACLE);
sb.append(host).append(":").append(port);
} else if (Constants.SQLSERVER.equals(type.name())) {
sb.append(Constants.JDBC_SQLSERVER);
sb.append(host).append(":").append(port);
}
return sb.toString();
}
/**
* delete datasource
*
* @param loginUser
* @param datasourceId
* @return
*/
@Transactional(value = "TransactionManager",rollbackFor = Exception.class)
public Result delete(User loginUser, int datasourceId) {
Result result = new Result();
try {
//query datasource by id
DataSource dataSource = dataSourceMapper.selectById(datasourceId);
if(dataSource == null){
logger.error("resource id {} not exist", datasourceId);
putMsg(result, Status.RESOURCE_NOT_EXIST);
return result;
}
if(loginUser.getId() != dataSource.getUserId() && loginUser.getUserType() != UserType.ADMIN_USER){
putMsg(result, Status.USER_NO_OPERATION_PERM);
return result;
}
dataSourceMapper.deleteById(datasourceId);
datasourceUserMapper.deleteByDatasourceId(datasourceId);
putMsg(result, Status.SUCCESS);
} catch (Exception e) {
logger.error("delete datasource fail",e);
throw new RuntimeException("delete datasource fail");
}
return result;
}
/**
* unauthorized datasource
*
* @param loginUser
* @param userId
* @return
*/
public Map<String, Object> unauthDatasource(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>();
//only admin operate
if (!isAdmin(loginUser)) {
putMsg(result, Status.USER_NO_OPERATION_PERM);
return result;
}
/**
* query all data sources except userId
*/
List<DataSource> resultList = new ArrayList<>();
List<DataSource> datasourceList = dataSourceMapper.queryDatasourceExceptUserId(userId);
Set<DataSource> datasourceSet = null;
if (datasourceList != null && datasourceList.size() > 0) {
datasourceSet = new HashSet<>(datasourceList);
List<DataSource> authedDataSourceList = dataSourceMapper.queryAuthedDatasource(userId);
Set<DataSource> authedDataSourceSet = null;
if (authedDataSourceList != null && authedDataSourceList.size() > 0) {
authedDataSourceSet = new HashSet<>(authedDataSourceList);
datasourceSet.removeAll(authedDataSourceSet);
}
resultList = new ArrayList<>(datasourceSet);
}
result.put(Constants.DATA_LIST, resultList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* authorized datasource
*
* @param loginUser
* @param userId
* @return
*/
public Map<String, Object> authedDatasource(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>(5);
if (!isAdmin(loginUser)) {
putMsg(result, Status.USER_NO_OPERATION_PERM);
return result;
}
List<DataSource> authedDatasourceList = dataSourceMapper.queryAuthedDatasource(userId);
result.put(Constants.DATA_LIST, authedDatasourceList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* get host and port by address
*
* @param address
* @return
*/
private String[] getHostsAndPort(String address) {
String[] result = new String[2];
String[] tmpArray = address.split(org.apache.dolphinscheduler.common.Constants.DOUBLE_SLASH);
String hostsAndPorts = tmpArray[tmpArray.length - 1];
StringBuilder hosts = new StringBuilder();
String[] hostPortArray = hostsAndPorts.split(org.apache.dolphinscheduler.common.Constants.COMMA);
String port = hostPortArray[0].split(org.apache.dolphinscheduler.common.Constants.COLON)[1];
for (String hostPort : hostPortArray) {
hosts.append(hostPort.split(org.apache.dolphinscheduler.common.Constants.COLON)[0]).append(org.apache.dolphinscheduler.common.Constants.COMMA);
}
hosts.deleteCharAt(hosts.length() - 1);
result[0] = hosts.toString();
result[1] = port;
return result;
}
}

540
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ExecutorService.java

@ -0,0 +1,540 @@
/*
* 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.service;
import org.apache.dolphinscheduler.api.enums.ExecuteType;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Constants;
import org.apache.dolphinscheduler.common.enums.*;
import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.dao.ProcessDao;
import org.apache.dolphinscheduler.dao.entity.*;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessInstanceMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.util.*;
import static org.apache.dolphinscheduler.common.Constants.*;
/**
* executor service
*/
@Service
public class ExecutorService extends BaseService{
private static final Logger logger = LoggerFactory.getLogger(ExecutorService.class);
@Autowired
private ProjectMapper projectMapper;
@Autowired
private ProjectService projectService;
@Autowired
private ProcessDefinitionMapper processDefinitionMapper;
@Autowired
private ProcessDefinitionService processDefinitionService;
@Autowired
private ProcessInstanceMapper processInstanceMapper;
@Autowired
private ProcessDao processDao;
/**
* execute process instance
*
* @param loginUser login user
* @param projectName project name
* @param processDefinitionId process Definition Id
* @param cronTime cron time
* @param commandType command type
* @param failureStrategy failuer strategy
* @param startNodeList start nodelist
* @param taskDependType node dependency type
* @param warningType warning type
* @param warningGroupId notify group id
* @param receivers receivers
* @param receiversCc receivers cc
* @param timeout timeout
* @return
*/
public Map<String, Object> execProcessInstance(User loginUser, String projectName,
int processDefinitionId, String cronTime, CommandType commandType,
FailureStrategy failureStrategy, String startNodeList,
TaskDependType taskDependType, WarningType warningType, int warningGroupId,
String receivers, String receiversCc, RunMode runMode,
Priority processInstancePriority, int workerGroupId, Integer timeout) throws ParseException {
Map<String, Object> result = new HashMap<>(5);
// timeout is valid
if (timeout <= 0 || timeout > MAX_TASK_TIMEOUT) {
putMsg(result,Status.TASK_TIMEOUT_PARAMS_ERROR);
return result;
}
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResultAndAuth = checkResultAndAuth(loginUser, projectName, project);
if (checkResultAndAuth != null){
return checkResultAndAuth;
}
// check process define release state
ProcessDefinition processDefinition = processDefinitionMapper.selectById(processDefinitionId);
result = checkProcessDefinitionValid(processDefinition, processDefinitionId);
if(result.get(Constants.STATUS) != Status.SUCCESS){
return result;
}
if (!checkTenantSuitable(processDefinition)){
logger.error("there is not any vaild tenant for the process definition: id:{},name:{}, ",
processDefinition.getId(), processDefinition.getName());
putMsg(result, Status.TENANT_NOT_SUITABLE);
return result;
}
/**
* create command
*/
int create = this.createCommand(commandType, processDefinitionId,
taskDependType, failureStrategy, startNodeList, cronTime, warningType, loginUser.getId(),
warningGroupId, runMode,processInstancePriority, workerGroupId);
if(create > 0 ){
/**
* according to the process definition ID updateProcessInstance and CC recipient
*/
processDefinition.setReceivers(receivers);
processDefinition.setReceiversCc(receiversCc);
processDefinitionMapper.updateById(processDefinition);
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.START_PROCESS_INSTANCE_ERROR);
}
return result;
}
/**
* check whether the process definition can be executed
*
* @param processDefinition
* @param processDefineId
* @return
*/
public Map<String, Object> checkProcessDefinitionValid(ProcessDefinition processDefinition, int processDefineId){
Map<String, Object> result = new HashMap<>(5);
if (processDefinition == null) {
// check process definition exists
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST,processDefineId);
} else if (processDefinition.getReleaseState() != ReleaseState.ONLINE) {
// check process definition online
putMsg(result, Status.PROCESS_DEFINE_NOT_RELEASE,processDefineId);
}else{
result.put(Constants.STATUS, Status.SUCCESS);
}
return result;
}
/**
* do action to process instancepause, stop, repeat, recover from pause, recover from stop
*
* @param loginUser
* @param projectName
* @param processInstanceId
* @param executeType
* @return
*/
public Map<String, Object> execute(User loginUser, String projectName, Integer processInstanceId, ExecuteType executeType) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = checkResultAndAuth(loginUser, projectName, project);
if (checkResult != null) {
return checkResult;
}
ProcessInstance processInstance = processDao.findProcessInstanceDetailById(processInstanceId);
if (processInstance == null) {
putMsg(result, Status.PROCESS_INSTANCE_NOT_EXIST, processInstanceId);
return result;
}
ProcessDefinition processDefinition = processDao.findProcessDefineById(processInstance.getProcessDefinitionId());
if(executeType != ExecuteType.STOP && executeType != ExecuteType.PAUSE){
result = checkProcessDefinitionValid(processDefinition, processInstance.getProcessDefinitionId());
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
}
checkResult = checkExecuteType(processInstance, executeType);
Status status = (Status) checkResult.get(Constants.STATUS);
if (status != Status.SUCCESS) {
return checkResult;
}
if (!checkTenantSuitable(processDefinition)){
logger.error("there is not any vaild tenant for the process definition: id:{},name:{}, ",
processDefinition.getId(), processDefinition.getName());
putMsg(result, Status.TENANT_NOT_SUITABLE);
}
switch (executeType) {
case REPEAT_RUNNING:
result = insertCommand(loginUser, processInstanceId, processDefinition.getId(), CommandType.REPEAT_RUNNING);
break;
case RECOVER_SUSPENDED_PROCESS:
result = insertCommand(loginUser, processInstanceId, processDefinition.getId(), CommandType.RECOVER_SUSPENDED_PROCESS);
break;
case START_FAILURE_TASK_PROCESS:
result = insertCommand(loginUser, processInstanceId, processDefinition.getId(), CommandType.START_FAILURE_TASK_PROCESS);
break;
case STOP:
if (processInstance.getState() == ExecutionStatus.READY_STOP) {
putMsg(result, Status.PROCESS_INSTANCE_ALREADY_CHANGED, processInstance.getName(), processInstance.getState());
} else {
processInstance.setCommandType(CommandType.STOP);
processInstance.addHistoryCmd(CommandType.STOP);
processDao.updateProcessInstance(processInstance);
result = updateProcessInstanceState(processInstanceId, ExecutionStatus.READY_STOP);
}
break;
case PAUSE:
if (processInstance.getState() == ExecutionStatus.READY_PAUSE) {
putMsg(result, Status.PROCESS_INSTANCE_ALREADY_CHANGED, processInstance.getName(), processInstance.getState());
} else {
processInstance.setCommandType(CommandType.PAUSE);
processInstance.addHistoryCmd(CommandType.PAUSE);
processDao.updateProcessInstance(processInstance);
result = updateProcessInstanceState(processInstanceId, ExecutionStatus.READY_PAUSE);
}
break;
default:
logger.error(String.format("unknown execute type : %s", executeType.toString()));
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, "unknown execute type");
break;
}
return result;
}
/**
* check tenant suitable
* @param processDefinition
* @return
*/
private boolean checkTenantSuitable(ProcessDefinition processDefinition) {
// checkTenantExists();
Tenant tenant = processDao.getTenantForProcess(processDefinition.getTenantId(),
processDefinition.getUserId());
if(tenant == null){
return false;
}
return true;
}
/**
* Check the state of process instance and the type of operation match
*
* @param processInstance
* @param executeType
* @return
*/
private Map<String, Object> checkExecuteType(ProcessInstance processInstance, ExecuteType executeType) {
Map<String, Object> result = new HashMap<>(5);
ExecutionStatus executionStatus = processInstance.getState();
boolean checkResult = false;
switch (executeType) {
case PAUSE:
case STOP:
if (executionStatus.typeIsRunning()) {
checkResult = true;
}
break;
case REPEAT_RUNNING:
if (executionStatus.typeIsFinished()) {
checkResult = true;
}
break;
case START_FAILURE_TASK_PROCESS:
if (executionStatus.typeIsFailure()) {
checkResult = true;
}
break;
case RECOVER_SUSPENDED_PROCESS:
if (executionStatus.typeIsPause()|| executionStatus.typeIsCancel()) {
checkResult = true;
}
default:
break;
}
if (!checkResult) {
putMsg(result,Status.PROCESS_INSTANCE_STATE_OPERATION_ERROR, processInstance.getName(), executionStatus.toString(), executeType.toString());
} else {
putMsg(result, Status.SUCCESS);
}
return result;
}
/**
* update process instance state
*
* @param processInstanceId
* @param executionStatus
* @return
*/
private Map<String, Object> updateProcessInstanceState(Integer processInstanceId, ExecutionStatus executionStatus) {
Map<String, Object> result = new HashMap<>(5);
int update = processDao.updateProcessInstanceState(processInstanceId, executionStatus);
if (update > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.EXECUTE_PROCESS_INSTANCE_ERROR);
}
return result;
}
/**
* insert command, used in the implementation of the page, re run, recovery (pause / failure) execution
*
* @param loginUser
* @param instanceId
* @param processDefinitionId
* @param commandType
* @return
*/
private Map<String, Object> insertCommand(User loginUser, Integer instanceId, Integer processDefinitionId, CommandType commandType) {
Map<String, Object> result = new HashMap<>(5);
Command command = new Command();
command.setCommandType(commandType);
command.setProcessDefinitionId(processDefinitionId);
command.setCommandParam(String.format("{\"%s\":%d}",
CMDPARAM_RECOVER_PROCESS_ID_STRING, instanceId));
command.setExecutorId(loginUser.getId());
if(!processDao.verifyIsNeedCreateCommand(command)){
putMsg(result, Status.PROCESS_INSTANCE_EXECUTING_COMMAND,processDefinitionId);
return result;
}
int create = processDao.createCommand(command);
if (create > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.EXECUTE_PROCESS_INSTANCE_ERROR);
}
return result;
}
/**
* check if subprocesses are offline before starting process definition
* @param processDefineId
* @return
*/
public Map<String, Object> startCheckByProcessDefinedId(int processDefineId) {
Map<String, Object> result = new HashMap<String, Object>();
if (processDefineId == 0){
logger.error("process definition id is null");
putMsg(result,Status.REQUEST_PARAMS_NOT_VALID_ERROR,"process definition id");
}
List<Integer> ids = new ArrayList<>();
processDao.recurseFindSubProcessId(processDefineId, ids);
Integer[] idArray = ids.toArray(new Integer[ids.size()]);
if (ids.size() > 0){
List<ProcessDefinition> processDefinitionList;
processDefinitionList = processDefinitionMapper.queryDefinitionListByIdList(idArray);
if (processDefinitionList != null && processDefinitionList.size() > 0){
for (ProcessDefinition processDefinition : processDefinitionList){
/**
* if there is no online process, exit directly
*/
if (processDefinition.getReleaseState() != ReleaseState.ONLINE){
putMsg(result,Status.PROCESS_DEFINE_NOT_RELEASE, processDefinition.getName());
logger.info("not release process definition id: {} , name : {}",
processDefinition.getId(), processDefinition.getName());
return result;
}
}
}
}
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query recipients and copyers by process definition id or processInstanceId
*
* @param processDefineId
* @return
*/
public Map<String, Object> getReceiverCc(Integer processDefineId,Integer processInstanceId) {
Map<String, Object> result = new HashMap<>();
logger.info("processInstanceId {}",processInstanceId);
if(processDefineId == null && processInstanceId == null){
throw new RuntimeException("You must set values for parameters processDefineId or processInstanceId");
}
if(processDefineId == null && processInstanceId != null) {
ProcessInstance processInstance = processInstanceMapper.selectById(processInstanceId);
if (processInstance == null) {
throw new RuntimeException("processInstanceId is not exists");
}
processDefineId = processInstance.getProcessDefinitionId();
}
ProcessDefinition processDefinition = processDefinitionMapper.selectById(processDefineId);
if (processDefinition == null){
throw new RuntimeException(String.format("processDefineId %d is not exists",processDefineId));
}
String receivers = processDefinition.getReceivers();
String receiversCc = processDefinition.getReceiversCc();
Map<String,String> dataMap = new HashMap<>();
dataMap.put(Constants.RECEIVERS,receivers);
dataMap.put(Constants.RECEIVERS_CC,receiversCc);
result.put(Constants.DATA_LIST, dataMap);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* create command
*
* @param commandType
* @param processDefineId
* @param nodeDep
* @param failureStrategy
* @param startNodeList
* @param schedule
* @param warningType
* @param excutorId
* @param warningGroupId
* @param runMode
* @return
* @throws ParseException
*/
private int createCommand(CommandType commandType, int processDefineId,
TaskDependType nodeDep, FailureStrategy failureStrategy,
String startNodeList, String schedule, WarningType warningType,
int excutorId, int warningGroupId,
RunMode runMode,Priority processInstancePriority, int workerGroupId) throws ParseException {
/**
* instantiate command schedule instance
*/
Command command = new Command();
Map<String,String> cmdParam = new HashMap<>();
if(commandType == null){
command.setCommandType(CommandType.START_PROCESS);
}else{
command.setCommandType(commandType);
}
command.setProcessDefinitionId(processDefineId);
if(nodeDep != null){
command.setTaskDependType(nodeDep);
}
if(failureStrategy != null){
command.setFailureStrategy(failureStrategy);
}
if(StringUtils.isNotEmpty(startNodeList)){
cmdParam.put(CMDPARAM_START_NODE_NAMES, startNodeList);
}
if(warningType != null){
command.setWarningType(warningType);
}
command.setCommandParam(JSONUtils.toJson(cmdParam));
command.setExecutorId(excutorId);
command.setWarningGroupId(warningGroupId);
command.setProcessInstancePriority(processInstancePriority);
command.setWorkerGroupId(workerGroupId);
Date start = null;
Date end = null;
if(StringUtils.isNotEmpty(schedule)){
String[] interval = schedule.split(",");
if(interval.length == 2){
start = DateUtils.getScheduleDate(interval[0]);
end = DateUtils.getScheduleDate(interval[1]);
}
}
if(commandType == CommandType.COMPLEMENT_DATA){
runMode = (runMode == null) ? RunMode.RUN_MODE_SERIAL : runMode;
if(runMode == RunMode.RUN_MODE_SERIAL){
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_START_DATE, DateUtils.dateToString(start));
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_END_DATE, DateUtils.dateToString(end));
command.setCommandParam(JSONUtils.toJson(cmdParam));
return processDao.createCommand(command);
}else if (runMode == RunMode.RUN_MODE_PARALLEL){
int runCunt = 0;
while(!start.after(end)){
runCunt += 1;
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_START_DATE, DateUtils.dateToString(start));
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_END_DATE, DateUtils.dateToString(start));
command.setCommandParam(JSONUtils.toJson(cmdParam));
processDao.createCommand(command);
start = DateUtils.getSomeDay(start, 1);
}
return runCunt;
}
}else{
command.setCommandParam(JSONUtils.toJson(cmdParam));
return processDao.createCommand(command);
}
return 0;
}
/**
* check result and auth
*
* @param loginUser
* @param projectName
* @param project
* @return
*/
private Map<String, Object> checkResultAndAuth(User loginUser, String projectName, Project project) {
// check project auth
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status status = (Status) checkResult.get(Constants.STATUS);
if (status != Status.SUCCESS) {
return checkResult;
}
return null;
}
}

91
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java

@ -0,0 +1,91 @@
/*
* 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.service;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.log.LogClient;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.dao.ProcessDao;
import org.apache.dolphinscheduler.dao.entity.TaskInstance;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* log service
*/
@Service
public class LoggerService {
private static final Logger logger = LoggerFactory.getLogger(LoggerService.class);
@Autowired
private ProcessDao processDao;
/**
* view log
*
* @param taskInstId
* @param skipLineNum
* @param limit
* @return
*/
public Result queryLog(int taskInstId, int skipLineNum, int limit) {
TaskInstance taskInstance = processDao.findTaskInstanceById(taskInstId);
if (taskInstance == null){
return new Result(Status.TASK_INSTANCE_NOT_FOUND.getCode(), Status.TASK_INSTANCE_NOT_FOUND.getMsg());
}
String host = taskInstance.getHost();
if(StringUtils.isEmpty(host)){
return new Result(Status.TASK_INSTANCE_NOT_FOUND.getCode(), Status.TASK_INSTANCE_NOT_FOUND.getMsg());
}
Result result = new Result(Status.SUCCESS.getCode(), Status.SUCCESS.getMsg());
logger.info("log host : {} , logPath : {} , logServer port : {}",host,taskInstance.getLogPath(),Constants.RPC_PORT);
LogClient logClient = new LogClient(host, Constants.RPC_PORT);
String log = logClient.rollViewLog(taskInstance.getLogPath(),skipLineNum,limit);
result.setData(log);
logger.info(log);
return result;
}
/**
* get log size
*
* @param taskInstId
* @return
*/
public byte[] getLogBytes(int taskInstId) {
TaskInstance taskInstance = processDao.findTaskInstanceById(taskInstId);
if (taskInstance == null){
throw new RuntimeException("task instance is null");
}
String host = taskInstance.getHost();
LogClient logClient = new LogClient(host, Constants.RPC_PORT);
return logClient.getLogBytes(taskInstance.getLogPath());
}
}

127
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/MonitorService.java

@ -0,0 +1,127 @@
/*
* 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.service;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Constants;
import org.apache.dolphinscheduler.api.utils.ZookeeperMonitor;
import org.apache.dolphinscheduler.common.enums.ZKNodeType;
import org.apache.dolphinscheduler.dao.MonitorDBDao;
import org.apache.dolphinscheduler.common.model.MasterServer;
import org.apache.dolphinscheduler.dao.entity.MonitorRecord;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.entity.ZookeeperRecord;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* monitor service
*/
@Service
public class MonitorService extends BaseService{
/**
* query database state
*
* @return
*/
public Map<String,Object> queryDatabaseState(User loginUser) {
Map<String, Object> result = new HashMap<>(5);
List<MonitorRecord> monitorRecordList = MonitorDBDao.queryDatabaseState();
result.put(Constants.DATA_LIST, monitorRecordList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query master list
*
* @param loginUser
* @return
*/
public Map<String,Object> queryMaster(User loginUser) {
Map<String, Object> result = new HashMap<>(5);
List<MasterServer> masterServers = getServerListFromZK(true);
result.put(Constants.DATA_LIST, masterServers);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* query zookeeper state
*
* @return
*/
public Map<String,Object> queryZookeeperState(User loginUser) {
Map<String, Object> result = new HashMap<>(5);
List<ZookeeperRecord> zookeeperRecordList = ZookeeperMonitor.zookeeperInfoList();
result.put(Constants.DATA_LIST, zookeeperRecordList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query master list
*
* @param loginUser
* @return
*/
public Map<String,Object> queryWorker(User loginUser) {
Map<String, Object> result = new HashMap<>(5);
List<MasterServer> workerServers = getServerListFromZK(false);
result.put(Constants.DATA_LIST, workerServers);
putMsg(result,Status.SUCCESS);
return result;
}
public List<MasterServer> getServerListFromZK(boolean isMaster){
List<MasterServer> servers = new ArrayList<>();
ZookeeperMonitor zookeeperMonitor = null;
try{
zookeeperMonitor = new ZookeeperMonitor();
ZKNodeType zkNodeType = isMaster ? ZKNodeType.MASTER : ZKNodeType.WORKER;
servers = zookeeperMonitor.getServersList(zkNodeType);
}catch (Exception e){
throw e;
}finally {
if(zookeeperMonitor != null){
zookeeperMonitor.close();
}
}
return servers;
}
}

1120
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionService.java

File diff suppressed because it is too large Load Diff

723
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessInstanceService.java

@ -0,0 +1,723 @@
/*
* 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.service;
import org.apache.dolphinscheduler.api.dto.gantt.GanttDto;
import org.apache.dolphinscheduler.api.dto.gantt.Task;
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.common.enums.DependResult;
import org.apache.dolphinscheduler.common.enums.ExecutionStatus;
import org.apache.dolphinscheduler.common.enums.Flag;
import org.apache.dolphinscheduler.common.enums.TaskType;
import org.apache.dolphinscheduler.common.graph.DAG;
import org.apache.dolphinscheduler.common.model.TaskNode;
import org.apache.dolphinscheduler.common.model.TaskNodeRelation;
import org.apache.dolphinscheduler.common.process.Property;
import org.apache.dolphinscheduler.common.queue.ITaskQueue;
import org.apache.dolphinscheduler.common.queue.TaskQueueFactory;
import org.apache.dolphinscheduler.common.utils.*;
import org.apache.dolphinscheduler.common.utils.placeholder.BusinessTimeUtils;
import org.apache.dolphinscheduler.dao.ProcessDao;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.dolphinscheduler.dao.entity.*;
import org.apache.dolphinscheduler.dao.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
import static org.apache.dolphinscheduler.common.Constants.*;
/**
* process instance service
*/
@Service
public class ProcessInstanceService extends BaseDAGService {
private static final Logger logger = LoggerFactory.getLogger(ProcessInstanceService.class);
@Autowired
ProjectMapper projectMapper;
@Autowired
ProjectService projectService;
@Autowired
ProcessDao processDao;
@Autowired
ProcessInstanceMapper processInstanceMapper;
@Autowired
ProcessDefinitionMapper processDefineMapper;
@Autowired
ProcessDefinitionService processDefinitionService;
@Autowired
ExecutorService execService;
@Autowired
TaskInstanceMapper taskInstanceMapper;
@Autowired
LoggerService loggerService;
@Autowired
WorkerGroupMapper workerGroupMapper;
/**
* query process instance by id
*
* @param loginUser
* @param projectName
* @param processId
* @return
*/
public Map<String, Object> queryProcessInstanceById(User loginUser, String projectName, Integer processId) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
ProcessInstance processInstance = processDao.findProcessInstanceDetailById(processId);
String workerGroupName = "";
if(processInstance.getWorkerGroupId() == -1){
workerGroupName = DEFAULT;
}else{
WorkerGroup workerGroup = workerGroupMapper.selectById(processInstance.getWorkerGroupId());
if(workerGroup != null){
workerGroupName = DEFAULT;
}else{
workerGroupName = workerGroup.getName();
}
}
processInstance.setWorkerGroupName(workerGroupName);
ProcessDefinition processDefinition = processDao.findProcessDefineById(processInstance.getProcessDefinitionId());
processInstance.setReceivers(processDefinition.getReceivers());
processInstance.setReceiversCc(processDefinition.getReceiversCc());
result.put(Constants.DATA_LIST, processInstance);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* paging query process instance list, filtering according to project, process definition, time range, keyword, process status
*
* @param loginUser
* @param projectName
* @param processDefineId
* @param startDate
* @param endDate
* @param searchVal
* @param stateType
* @param pageNo
* @param pageSize
* @return
*/
public Map<String, Object> queryProcessInstanceList(User loginUser, String projectName, Integer processDefineId,
String startDate, String endDate,
String searchVal, ExecutionStatus stateType, String host,
Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
int[] statusArray = null;
String statesStr = null;
// filter by state
if (stateType != null) {
statusArray = new int[]{stateType.ordinal()};
}
if (statusArray != null) {
statesStr = Arrays.toString(statusArray).replace("[", "").replace("]", "");
}
Date start = null;
Date end = null;
try {
if (StringUtils.isNotEmpty(startDate)) {
start = DateUtils.getScheduleDate(startDate);
}
if (StringUtils.isNotEmpty(endDate)) {
end = DateUtils.getScheduleDate(endDate);
}
} catch (Exception e) {
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, "startDate,endDate");
return result;
}
Page<ProcessInstance> page = new Page(pageNo, pageSize);
IPage<ProcessInstance> processInstanceList =
processInstanceMapper.queryProcessInstanceListPaging(page,
project.getId(), processDefineId, searchVal, statusArray, host, start, end);
Set<String> exclusionSet = new HashSet<String>(){{
add(Constants.CLASS);
add("locations");
add("connects");
add("processInstanceJson");
}};
PageInfo pageInfo = new PageInfo<ProcessInstance>(pageNo, pageSize);
pageInfo.setTotalCount((int)processInstanceList.getTotal());
pageInfo.setLists(CollectionUtils.getListByExclusion(processInstanceList.getRecords(), exclusionSet));
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query task list by process instance id
*
* @param loginUser
* @param projectName
* @param processId
* @return
*/
public Map<String, Object> queryTaskListByProcessId(User loginUser, String projectName, Integer processId) throws IOException {
Map<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
ProcessInstance processInstance = processDao.findProcessInstanceDetailById(processId);
List<TaskInstance> taskInstanceList = processDao.findValidTaskListByProcessId(processId);
AddDependResultForTaskList(taskInstanceList);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put(PROCESS_INSTANCE_STATE, processInstance.getState().toString());
resultMap.put(TASK_LIST, taskInstanceList);
result.put(Constants.DATA_LIST, resultMap);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* add dependent result for dependent task
* @param taskInstanceList
*/
private void AddDependResultForTaskList(List<TaskInstance> taskInstanceList) throws IOException {
for(TaskInstance taskInstance: taskInstanceList){
if(taskInstance.getTaskType().toUpperCase().equals(TaskType.DEPENDENT.toString())){
Result logResult = loggerService.queryLog(
taskInstance.getId(), 0, 4098);
if(logResult.getCode() == Status.SUCCESS.ordinal()){
String log = (String) logResult.getData();
Map<String, DependResult> resultMap = parseLogForDependentResult(log);
taskInstance.setDependentResult(JSONUtils.toJson(resultMap));
}
}
}
}
public Map<String,DependResult> parseLogForDependentResult(String log) throws IOException {
Map<String, DependResult> resultMap = new HashMap<>();
if(StringUtils.isEmpty(log)){
return resultMap;
}
BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(log.getBytes(Charset.forName("utf8"))), Charset.forName("utf8")));
String line;
while ((line = br.readLine()) != null) {
if(line.contains(DEPENDENT_SPLIT)){
String[] tmpStringArray = line.split(":\\|\\|");
if(tmpStringArray.length != 2){
continue;
}
String dependResultString = tmpStringArray[1];
String[] dependStringArray = dependResultString.split(",");
if(dependStringArray.length != 2){
continue;
}
String key = dependStringArray[0].trim();
DependResult dependResult = DependResult.valueOf(dependStringArray[1].trim());
resultMap.put(key, dependResult);
}
}
return resultMap;
}
/**
* query sub process instance detail info by task id
*
* @param loginUser
* @param projectName
* @param taskId
* @return
*/
public Map<String, Object> querySubProcessInstanceByTaskId(User loginUser, String projectName, Integer taskId) {
Map<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
TaskInstance taskInstance = processDao.findTaskInstanceById(taskId);
if (taskInstance == null) {
putMsg(result, Status.TASK_INSTANCE_NOT_EXISTS, taskId);
return result;
}
if (!taskInstance.isSubProcess()) {
putMsg(result, Status.TASK_INSTANCE_NOT_SUB_WORKFLOW_INSTANCE, taskInstance.getName());
return result;
}
ProcessInstance subWorkflowInstance = processDao.findSubProcessInstance(
taskInstance.getProcessInstanceId(), taskInstance.getId());
if (subWorkflowInstance == null) {
putMsg(result, Status.SUB_PROCESS_INSTANCE_NOT_EXIST, taskId);
return result;
}
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("subProcessInstanceId", subWorkflowInstance.getId());
result.put(Constants.DATA_LIST, dataMap);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* update process instance
*
* @param loginUser
* @param projectName
* @param processInstanceId
* @param processInstanceJson
* @param scheduleTime
* @param syncDefine
* @param flag
* @param locations
* @param connects
* @return
*/
public Map<String, Object> updateProcessInstance(User loginUser, String projectName, Integer processInstanceId,
String processInstanceJson, String scheduleTime, Boolean syncDefine,
Flag flag, String locations, String connects) throws ParseException {
Map<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
//check project permission
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
//check process instance exists
ProcessInstance processInstance = processDao.findProcessInstanceDetailById(processInstanceId);
if (processInstance == null) {
putMsg(result, Status.PROCESS_INSTANCE_NOT_EXIST, processInstanceId);
return result;
}
//check process instance status
if (!processInstance.getState().typeIsFinished()) {
putMsg(result, Status.PROCESS_INSTANCE_STATE_OPERATION_ERROR,
processInstance.getName(), processInstance.getState().toString(), "update");
return result;
}
Date schedule = null;
if (scheduleTime != null) {
schedule = DateUtils.getScheduleDate(scheduleTime);
} else {
schedule = processInstance.getScheduleTime();
}
processInstance.setScheduleTime(schedule);
processInstance.setLocations(locations);
processInstance.setConnects(connects);
String globalParams = null;
String originDefParams = null;
int timeout = processInstance.getTimeout();
ProcessDefinition processDefinition = processDao.findProcessDefineById(processInstance.getProcessDefinitionId());
if (StringUtils.isNotEmpty(processInstanceJson)) {
ProcessData processData = JSONUtils.parseObject(processInstanceJson, ProcessData.class);
//check workflow json is valid
Map<String, Object> checkFlowJson = processDefinitionService.checkProcessNodeList(processData, processInstanceJson);
if (checkFlowJson.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
originDefParams = JSONUtils.toJson(processData.getGlobalParams());
List<Property> globalParamList = processData.getGlobalParams();
Map<String, String> globalParamMap = globalParamList.stream().collect(Collectors.toMap(Property::getProp, Property::getValue));
globalParams = ParameterUtils.curingGlobalParams(globalParamMap, globalParamList,
processInstance.getCmdTypeIfComplement(), schedule);
timeout = processData.getTimeout();
processInstance.setTimeout(timeout);
Tenant tenant = processDao.getTenantForProcess(processData.getTenantId(),
processDefinition.getUserId());
if(tenant != null){
processInstance.setTenantCode(tenant.getTenantCode());
}
processInstance.setProcessInstanceJson(processInstanceJson);
processInstance.setGlobalParams(globalParams);
}
// int update = processDao.updateProcessInstance(processInstanceId, processInstanceJson,
// globalParams, schedule, flag, locations, connects);
int update = processDao.updateProcessInstance(processInstance);
int updateDefine = 1;
if (syncDefine && StringUtils.isNotEmpty(processInstanceJson)) {
processDefinition.setProcessDefinitionJson(processInstanceJson);
processDefinition.setGlobalParams(originDefParams);
processDefinition.setLocations(locations);
processDefinition.setConnects(connects);
processDefinition.setTimeout(timeout);
updateDefine = processDefineMapper.updateById(processDefinition);
}
if (update > 0 && updateDefine > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.UPDATE_PROCESS_INSTANCE_ERROR);
}
return result;
}
/**
* query parent process instance detail info by sub process instance id
*
* @param loginUser
* @param projectName
* @param subId
* @return
*/
public Map<String, Object> queryParentInstanceBySubId(User loginUser, String projectName, Integer subId) {
Map<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
ProcessInstance subInstance = processDao.findProcessInstanceDetailById(subId);
if (subInstance == null) {
putMsg(result, Status.PROCESS_INSTANCE_NOT_EXIST, subId);
return result;
}
if (subInstance.getIsSubProcess() == Flag.NO) {
putMsg(result, Status.PROCESS_INSTANCE_NOT_SUB_PROCESS_INSTANCE, subInstance.getName());
return result;
}
ProcessInstance parentWorkflowInstance = processDao.findParentProcessInstance(subId);
if (parentWorkflowInstance == null) {
putMsg(result, Status.SUB_PROCESS_INSTANCE_NOT_EXIST);
return result;
}
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("parentWorkflowInstance", parentWorkflowInstance.getId());
result.put(Constants.DATA_LIST, dataMap);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* delete process instance by id, at the same timedelete task instance and their mapping relation data
* @param loginUser
* @param projectName
* @param processInstanceId
* @param tasksQueue
* @return
*/
public Map<String, Object> deleteProcessInstanceById(User loginUser, String projectName, Integer processInstanceId,ITaskQueue tasksQueue) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
ProcessInstance processInstance = processDao.findProcessInstanceDetailById(processInstanceId);
List<TaskInstance> taskInstanceList = processDao.findValidTaskListByProcessId(processInstanceId);
//process instance priority
int processInstancePriority = processInstance.getProcessInstancePriority().ordinal();
if (processInstance == null) {
putMsg(result, Status.PROCESS_INSTANCE_NOT_EXIST, processInstanceId);
return result;
}
// delete zk queue
if (CollectionUtils.isNotEmpty(taskInstanceList)){
for (TaskInstance taskInstance : taskInstanceList){
// task instance priority
int taskInstancePriority = taskInstance.getTaskInstancePriority().ordinal();
StringBuilder nodeValueSb = new StringBuilder(100);
nodeValueSb.append(processInstancePriority)
.append(UNDERLINE)
.append(processInstanceId)
.append(UNDERLINE)
.append(taskInstancePriority)
.append(UNDERLINE)
.append(taskInstance.getId())
.append(UNDERLINE);
int taskWorkerGroupId = processDao.getTaskWorkerGroupId(taskInstance);
WorkerGroup workerGroup = workerGroupMapper.selectById(taskWorkerGroupId);
if(workerGroup == null){
nodeValueSb.append(DEFAULT_WORKER_ID);
}else {
String ips = workerGroup.getIpList();
StringBuilder ipSb = new StringBuilder(100);
String[] ipArray = ips.split(COMMA);
for (String ip : ipArray) {
long ipLong = IpUtils.ipToLong(ip);
ipSb.append(ipLong).append(COMMA);
}
if(ipSb.length() > 0) {
ipSb.deleteCharAt(ipSb.length() - 1);
}
nodeValueSb.append(ipSb);
}
try {
logger.info("delete task queue node : {}",nodeValueSb.toString());
tasksQueue.removeNode(org.apache.dolphinscheduler.common.Constants.SCHEDULER_TASKS_QUEUE, nodeValueSb.toString());
}catch (Exception e){
logger.error("delete task queue node : {}", nodeValueSb.toString());
}
}
}
// delete database cascade
int delete = processDao.deleteWorkProcessInstanceById(processInstanceId);
processDao.deleteAllSubWorkProcessByParentId(processInstanceId);
processDao.deleteWorkProcessMapByParentId(processInstanceId);
if (delete > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.DELETE_PROCESS_INSTANCE_BY_ID_ERROR);
}
return result;
}
/**
* batch delete process instance by ids, at the same timedelete task instance and their mapping relation data
*
* @param loginUser
* @param projectName
* @param processInstanceIds
* @return
*/
public Map<String, Object> batchDeleteProcessInstanceByIds(User loginUser, String projectName, String processInstanceIds) {
// task queue
ITaskQueue tasksQueue = TaskQueueFactory.getTaskQueueInstance();
Map<String, Object> result = new HashMap<>(5);
List<Integer> deleteFailedIdList = new ArrayList<Integer>();
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
if(StringUtils.isNotEmpty(processInstanceIds)){
String[] processInstanceIdArray = processInstanceIds.split(",");
for (String strProcessInstanceId:processInstanceIdArray) {
int processInstanceId = Integer.parseInt(strProcessInstanceId);
try {
deleteProcessInstanceById(loginUser, projectName, processInstanceId,tasksQueue);
} catch (Exception e) {
deleteFailedIdList.add(processInstanceId);
}
}
}
if(deleteFailedIdList.size() > 0){
putMsg(result, Status.BATCH_DELETE_PROCESS_INSTANCE_BY_IDS_ERROR,StringUtils.join(deleteFailedIdList.toArray(),","));
}else{
putMsg(result, Status.SUCCESS);
}
return result;
}
/**
* view process instance variables
*
* @param processInstanceId
* @return
*/
public Map<String, Object> viewVariables( Integer processInstanceId) throws Exception {
Map<String, Object> result = new HashMap<>(5);
ProcessInstance processInstance = processInstanceMapper.queryDetailById(processInstanceId);
if (processInstance == null) {
throw new RuntimeException("workflow instance is null");
}
Map<String, String> timeParams = BusinessTimeUtils
.getBusinessTime(processInstance.getCmdTypeIfComplement(),
processInstance.getScheduleTime());
String workflowInstanceJson = processInstance.getProcessInstanceJson();
ProcessData workflowData = JSONUtils.parseObject(workflowInstanceJson, ProcessData.class);
String userDefinedParams = processInstance.getGlobalParams();
// global params
List<Property> globalParams = new ArrayList<>();
if (userDefinedParams != null && userDefinedParams.length() > 0) {
globalParams = JSON.parseArray(userDefinedParams, Property.class);
}
List<TaskNode> taskNodeList = workflowData.getTasks();
// global param string
String globalParamStr = JSON.toJSONString(globalParams);
globalParamStr = ParameterUtils.convertParameterPlaceholders(globalParamStr, timeParams);
globalParams = JSON.parseArray(globalParamStr, Property.class);
for (Property property : globalParams) {
timeParams.put(property.getProp(), property.getValue());
}
// local params
Map<String, Map<String,Object>> localUserDefParams = new HashMap<>();
for (TaskNode taskNode : taskNodeList) {
String parameter = taskNode.getParams();
Map<String, String> map = JSONUtils.toMap(parameter);
String localParams = map.get(LOCAL_PARAMS);
if (localParams != null && !localParams.isEmpty()) {
localParams = ParameterUtils.convertParameterPlaceholders(localParams, timeParams);
List<Property> localParamsList = JSON.parseArray(localParams, Property.class);
Map<String,Object> localParamsMap = new HashMap<>();
localParamsMap.put("taskType",taskNode.getType());
localParamsMap.put("localParamsList",localParamsList);
if (localParamsList.size() > 0) {
localUserDefParams.put(taskNode.getName(), localParamsMap);
}
}
}
Map<String, Object> resultMap = new HashMap<>();
resultMap.put(GLOBAL_PARAMS, globalParams);
resultMap.put(LOCAL_PARAMS, localUserDefParams);
result.put(Constants.DATA_LIST, resultMap);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* encapsulation gantt structure
*
* @param processInstanceId
* @return
* @throws Exception
*/
public Map<String, Object> viewGantt(Integer processInstanceId) throws Exception {
Map<String, Object> result = new HashMap<>();
ProcessInstance processInstance = processInstanceMapper.queryDetailById(processInstanceId);
if (processInstance == null) {
throw new RuntimeException("workflow instance is null");
}
GanttDto ganttDto = new GanttDto();
DAG<String, TaskNode, TaskNodeRelation> dag = processInstance2DAG(processInstance);
//topological sort
List<String> nodeList = dag.topologicalSort();
ganttDto.setTaskNames(nodeList);
List<Task> taskList = new ArrayList<>();
for (String node : nodeList) {
TaskInstance taskInstance = taskInstanceMapper.queryByInstanceIdAndName(processInstanceId, node);
if (taskInstance == null) {
continue;
}
Date startTime = taskInstance.getStartTime() == null ? new Date() : taskInstance.getStartTime();
Date endTime = taskInstance.getEndTime() == null ? new Date() : taskInstance.getEndTime();
Task task = new Task();
task.setTaskName(taskInstance.getName());
task.getStartDate().add(startTime.getTime());
task.getEndDate().add(endTime.getTime());
task.setIsoStart(startTime);
task.setIsoEnd(endTime);
task.setStatus(taskInstance.getState().toString());
task.setExecutionDate(taskInstance.getStartTime());
task.setDuration(DateUtils.format2Readable(endTime.getTime() - startTime.getTime()));
taskList.add(task);
}
ganttDto.setTasks(taskList);
result.put(Constants.DATA_LIST, ganttDto);
putMsg(result, Status.SUCCESS);
return result;
}
}

396
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProjectService.java

@ -0,0 +1,396 @@
/*
* 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.service;
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.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.ProjectUser;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import static org.apache.dolphinscheduler.api.utils.CheckUtils.checkDesc;
/**
* project service
*HttpTask./
**/
@Service
public class ProjectService extends BaseService{
private static final Logger logger = LoggerFactory.getLogger(ProjectService.class);
@Autowired
private ProjectMapper projectMapper;
@Autowired
private ProjectUserMapper projectUserMapper;
@Autowired
private ProcessDefinitionMapper processDefinitionMapper;
/**
* create project
*
* @param loginUser
* @param name
* @param desc
* @return
*/
public Map<String, Object> createProject(User loginUser, String name, String desc) {
Map<String, Object> result = new HashMap<>(5);
Map<String, Object> descCheck = checkDesc(desc);
if (descCheck.get(Constants.STATUS) != Status.SUCCESS) {
return descCheck;
}
Project project = projectMapper.queryByName(name);
if (project != null) {
putMsg(result, Status.PROJECT_ALREADY_EXISTS, name);
return result;
}
project = new Project();
Date now = new Date();
project.setName(name);
project.setDesc(desc);
project.setUserId(loginUser.getId());
project.setUserName(loginUser.getUserName());
project.setCreateTime(now);
project.setUpdateTime(now);
if (projectMapper.insert(project) > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.CREATE_PROJECT_ERROR);
}
return result;
}
/**
* query project details by id
*
* @param projectId
* @return
*/
public Map<String, Object> queryById(Integer projectId) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.selectById(projectId);
if (project != null) {
result.put(Constants.DATA_LIST, project);
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.PROJECT_NOT_FOUNT, projectId);
}
return result;
}
/**
* check project and authorization
* 检查项目权限
*
* @param loginUser
* @param project
* @param projectName
* @return
*/
public Map<String, Object> checkProjectAndAuth(User loginUser, Project project, String projectName) {
Map<String, Object> result = new HashMap<>(5);
if (project == null) {
putMsg(result, Status.PROJECT_NOT_FOUNT, projectName);
} else if (!checkReadPermission(loginUser, project)) {
// check read permission
putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), projectName);
}else {
putMsg(result, Status.SUCCESS);
}
return result;
}
/**
* admin can view all projects
* 如果是管理员,则所有项目都可见
*
* @param loginUser
* @param pageSize
* @param pageNo
* @param searchVal
* @return
*/
public Map<String, Object> queryProjectListPaging(User loginUser, Integer pageSize, Integer pageNo, String searchVal) {
Map<String, Object> result = new HashMap<>();
PageInfo pageInfo = new PageInfo<Project>(pageNo, pageSize);
Page<Project> page = new Page(pageNo, pageSize);
int userId = loginUser.getUserType() == UserType.ADMIN_USER ? 0 : loginUser.getId();
IPage<Project> projectIPage = projectMapper.queryProjectListPaging(page, userId, searchVal);
List<Project> projectList = projectIPage.getRecords();
if(userId != 0){
for (Project project : projectList) {
project.setPerm(org.apache.dolphinscheduler.common.Constants.DEFAULT_ADMIN_PERMISSION);
}
}
pageInfo.setTotalCount((int)projectIPage.getTotal());
pageInfo.setLists(projectList);
result.put(Constants.COUNT, (int)projectIPage.getTotal());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* delete project by id
*
* @param loginUser
* @param projectId
* @return
*/
public Map<String, Object> deleteProject(User loginUser, Integer projectId) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.selectById(projectId);
Map<String, Object> checkResult = getCheckResult(loginUser, project);
if (checkResult != null) {
return checkResult;
}
List<ProcessDefinition> processDefinitionList = processDefinitionMapper.queryAllDefinitionList(projectId);
if(processDefinitionList.size() > 0){
putMsg(result, Status.DELETE_PROJECT_ERROR_DEFINES_NOT_NULL);
return result;
}
int delete = projectMapper.deleteById(projectId);
if (delete > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.DELETE_PROJECT_ERROR);
}
return result;
}
/**
* get check result
*
* @param loginUser
* @param project
* @return
*/
private Map<String, Object> getCheckResult(User loginUser, Project project) {
Map<String, Object> checkResult = checkProjectAndAuth(loginUser, project, project.getName());
Status status = (Status) checkResult.get(Constants.STATUS);
if (status != Status.SUCCESS) {
return checkResult;
}
return null;
}
/**
* updateProcessInstance project
*
* @param loginUser
* @param projectId
* @param projectName
* @param desc
* @return
*/
public Map<String, Object> update(User loginUser, Integer projectId, String projectName, String desc) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.selectById(projectId);
Map<String, Object> checkResult = getCheckResult(loginUser, project);
if (checkResult != null) {
return checkResult;
}
Project tempProject = projectMapper.queryByName(projectName);
if (tempProject != null && tempProject.getId() != projectId) {
putMsg(result, Status.PROJECT_ALREADY_EXISTS, projectName);
return result;
}
project.setName(projectName);
project.setDesc(desc);
project.setUpdateTime(new Date());
int update = projectMapper.updateById(project);
if (update > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.UPDATE_PROJECT_ERROR);
}
return result;
}
/**
* query unauthorized project
*
* @param loginUser
* @param userId
* @return
*/
public Map<String, Object> queryUnauthorizedProject(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
/**
* query all project list except specified userId
*/
List<Project> projectList = projectMapper.queryProjectExceptUserId(userId);
List<Project> resultList = new ArrayList<>();
Set<Project> projectSet = null;
if (projectList != null && projectList.size() > 0) {
projectSet = new HashSet<>(projectList);
List<Project> authedProjectList = projectMapper.queryAuthedProjectListByUserId(userId);
resultList = getUnauthorizedProjects(projectSet, authedProjectList);
}
result.put(Constants.DATA_LIST, resultList);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* get unauthorized project
*
* @param projectSet
* @param authedProjectList
* @return
*/
private List<Project> getUnauthorizedProjects(Set<Project> projectSet, List<Project> authedProjectList) {
List<Project> resultList;
Set<Project> authedProjectSet = null;
if (authedProjectList != null && authedProjectList.size() > 0) {
authedProjectSet = new HashSet<>(authedProjectList);
projectSet.removeAll(authedProjectSet);
}
resultList = new ArrayList<>(projectSet);
return resultList;
}
/**
* query authorized project
*
* @param loginUser
* @param userId
* @return
*/
public Map<String, Object> queryAuthorizedProject(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>();
if (checkAdmin(loginUser, result)) {
return result;
}
List<Project> projects = projectMapper.queryAuthedProjectListByUserId(userId);
result.put(Constants.DATA_LIST, projects);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* check whether have read permission
*
* @param user
* @param project
* @return
*/
private boolean checkReadPermission(User user, Project project) {
int permissionId = queryPermission(user, project);
return (permissionId & org.apache.dolphinscheduler.common.Constants.READ_PERMISSION) != 0;
}
/**
* query permission id
*
* @param user
* @param project
* @return
*/
private int queryPermission(User user, Project project) {
if (user.getUserType() == UserType.ADMIN_USER) {
return org.apache.dolphinscheduler.common.Constants.READ_PERMISSION;
}
if (project.getUserId() == user.getId()) {
return org.apache.dolphinscheduler.common.Constants.ALL_PERMISSIONS;
}
ProjectUser projectUser = projectUserMapper.queryProjectRelation(project.getId(), user.getId());
if (projectUser == null) {
return 0;
}
return projectUser.getPerm();
}
/**
* query all project list that have one or more process definitions.
* @return
*/
public Map<String, Object> queryAllProjectList() {
Map<String, Object> result = new HashMap<>();
List<Project> projects = projectMapper.selectList(null);
List<ProcessDefinition> processDefinitions = processDefinitionMapper.selectList(null);
if(projects != null){
Set set = new HashSet<>();
for (ProcessDefinition processDefinition : processDefinitions){
set.add(processDefinition.getProjectId());
}
List<Project> tempDeletelist = new ArrayList<Project>();
for (Project project : projects) {
if(!set.contains(project.getId())){
tempDeletelist.add(project);
}
}
projects.removeAll(tempDeletelist);
}
result.put(Constants.DATA_LIST, projects);
putMsg(result,Status.SUCCESS);
return result;
}
}

259
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/QueueService.java

@ -0,0 +1,259 @@
/*
* 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.service;
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.Queue;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.QueueMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* queue service
*/
@Service
public class QueueService extends BaseService {
private static final Logger logger = LoggerFactory.getLogger(TenantService.class);
@Autowired
private QueueMapper queueMapper;
/**
* query queue list
*
* @param loginUser
* @return
*/
public Map<String, Object> queryList(User loginUser) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
List<Queue> queueList = queueMapper.selectList(null);
result.put(Constants.DATA_LIST, queueList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query queue list paging
*
* @param loginUser
* @param searchVal
* @param pageNo
* @param pageSize
* @return
*/
public Map<String, Object> queryList(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
Page<Queue> page = new Page(pageNo, pageSize);
IPage<Queue> queueList = queueMapper.queryQueuePaging(page, searchVal);
Integer count = (int)queueList.getTotal();
PageInfo<Queue> pageInfo = new PageInfo<>(pageNo, pageSize);
pageInfo.setTotalCount(count);
pageInfo.setLists(queueList.getRecords());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* create queue
*
* @param loginUser
* @param queue
* @param queueName
* @return
*/
public Map<String, Object> createQueue(User loginUser, String queue, String queueName) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
if(StringUtils.isEmpty(queue)){
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, queue);
return result;
}
if(StringUtils.isEmpty(queueName)){
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, queueName);
return result;
}
if (checkQueueNameExist(queueName)) {
putMsg(result, Status.QUEUE_NAME_EXIST, queueName);
return result;
}
if (checkQueueExist(queue)) {
putMsg(result, Status.QUEUE_VALUE_EXIST, queue);
return result;
}
Queue queueObj = new Queue();
Date now = new Date();
queueObj.setQueue(queue);
queueObj.setQueueName(queueName);
queueObj.setCreateTime(now);
queueObj.setUpdateTime(now);
queueMapper.insert(queueObj);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* update queue
*
* @param loginUser
* @param id
* @param queue
* @param queueName
* @return
*/
public Map<String, Object> updateQueue(User loginUser, int id, String queue, String queueName) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
Queue queueObj = queueMapper.selectById(id);
if (queueObj == null) {
putMsg(result, Status.QUEUE_NOT_EXIST, id);
return result;
}
// whether queue value or queueName is changed
if (queue.equals(queueObj.getQueue()) && queueName.equals(queueObj.getQueueName())) {
putMsg(result, Status.NEED_NOT_UPDATE_QUEUE);
return result;
}
// check queue name is exist
if (!queueName.equals(queueObj.getQueueName())) {
if(checkQueueNameExist(queueName)){
putMsg(result, Status.QUEUE_NAME_EXIST, queueName);
return result;
}
}
// check queue value is exist
if (!queue.equals(queueObj.getQueue())) {
if(checkQueueExist(queue)){
putMsg(result, Status.QUEUE_VALUE_EXIST, queue);
return result;
}
}
// update queue
Date now = new Date();
queueObj.setQueue(queue);
queueObj.setQueueName(queueName);
queueObj.setUpdateTime(now);
queueMapper.updateById(queueObj);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* verify queue and queueName
*
* @param queue
* @param queueName
* @return
*/
public Result verifyQueue(String queue, String queueName) {
Result result=new Result();
if (StringUtils.isEmpty(queue)) {
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, queue);
return result;
}
if (StringUtils.isEmpty(queueName)) {
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, queueName);
return result;
}
if(checkQueueNameExist(queueName)){
logger.error("queue name {} has exist, can't create again.", queueName);
putMsg(result, Status.QUEUE_NAME_EXIST, queueName);
return result;
}
if(checkQueueExist(queue)){
logger.error("queue value {} has exist, can't create again.", queue);
putMsg(result, Status.QUEUE_VALUE_EXIST, queue);
return result;
}
putMsg(result, Status.SUCCESS);
return result;
}
/**
* check queue exist
*
* @param queue
* @return
*/
private boolean checkQueueExist(String queue) {
return queueMapper.queryAllQueueList(queue, null).size()>0 ? false : true;
}
/**
* check queue name exist
*
* @param queueName
* @return
*/
private boolean checkQueueNameExist(String queueName) {
return queueMapper.queryAllQueueList(null ,queueName).size()>0 ? false : true;
}
}

897
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ResourcesService.java

@ -0,0 +1,897 @@
/*
* 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.service;
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.common.enums.ResourceType;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.common.utils.FileUtils;
import org.apache.dolphinscheduler.common.utils.HadoopUtils;
import org.apache.dolphinscheduler.common.utils.PropertyUtils;
import org.apache.dolphinscheduler.dao.entity.Resource;
import org.apache.dolphinscheduler.dao.entity.Tenant;
import org.apache.dolphinscheduler.dao.entity.UdfFunc;
import org.apache.dolphinscheduler.dao.entity.User;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections.BeanMap;
import org.apache.commons.lang.StringUtils;
import org.apache.dolphinscheduler.dao.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.text.MessageFormat;
import java.util.*;
import static org.apache.dolphinscheduler.common.Constants.*;
/**
* resources service
*/
@Service
public class ResourcesService extends BaseService {
private static final Logger logger = LoggerFactory.getLogger(ResourcesService.class);
@Autowired
private ResourceMapper resourcesMapper;
@Autowired
private UdfFuncMapper udfFunctionMapper;
@Autowired
private TenantMapper tenantMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private ResourceUserMapper resourceUserMapper;
/**
* create resource
*
* @param loginUser
* @param type
* @param name
* @param desc
* @param file
* @return
*/
@Transactional(value = "TransactionManager",rollbackFor = Exception.class)
public Result createResource(User loginUser,
String name,
String desc,
ResourceType type,
MultipartFile file) {
Result result = new Result();
// if hdfs not startup
if (!PropertyUtils.getResUploadStartupState()){
logger.error("resource upload startup state: {}", PropertyUtils.getResUploadStartupState());
putMsg(result, Status.HDFS_NOT_STARTUP);
return result;
}
// file is empty
if (file.isEmpty()) {
logger.error("file is empty: {}", file.getOriginalFilename());
putMsg(result, Status.RESOURCE_FILE_IS_EMPTY);
return result;
}
// file suffix
String fileSuffix = FileUtils.suffix(file.getOriginalFilename());
String nameSuffix = FileUtils.suffix(name);
// determine file suffix
if (!StringUtils.equals(fileSuffix, nameSuffix)) {
/**
* rename file suffix and original suffix must be consistent
* 重命名的后缀必须与原文件后缀一致
*/
logger.error("rename file suffix and original suffix must be consistent: {}", file.getOriginalFilename());
putMsg(result, Status.RESOURCE_SUFFIX_FORBID_CHANGE);
return result;
}
//
//If resource type is UDF, only jar packages are allowed to be uploaded, and the suffix must be .jar
if (Constants.UDF.equals(type.name())) {
if (!JAR.equalsIgnoreCase(fileSuffix)) {
logger.error(Status.UDF_RESOURCE_SUFFIX_NOT_JAR.getMsg());
putMsg(result, Status.UDF_RESOURCE_SUFFIX_NOT_JAR);
return result;
}
}
if (file.getSize() > Constants.maxFileSize) {
logger.error("file size is too large: {}", file.getOriginalFilename());
putMsg(result, Status.RESOURCE_SIZE_EXCEED_LIMIT);
return result;
}
// check resoure name exists
if (checkResourceExists(name, 0, type.ordinal())) {
logger.error("resource {} has exist, can't recreate", name);
putMsg(result, Status.RESOURCE_EXIST);
return result;
}
Date now = new Date();
Resource resource = new Resource(name,file.getOriginalFilename(),desc,loginUser.getId(),type,file.getSize(),now,now);
try {
resourcesMapper.insert(resource);
putMsg(result, Status.SUCCESS);
Map dataMap = new BeanMap(resource);
Map<String, Object> resultMap = new HashMap<String, Object>();
for (Object key : dataMap.keySet()) {
if (!"class".equalsIgnoreCase(key.toString())) {
resultMap.put(key.toString(), dataMap.get(key));
}
}
result.setData(resultMap);
} catch (Exception e) {
logger.error("resource already exists, can't recreate ", e);
putMsg(result, Status.CREATE_RESOURCE_ERROR);
return result;
}
// fail upload
if (!upload(loginUser, name, file, type)) {
logger.error("upload resource: {} file: {} failed.", name, file.getOriginalFilename());
putMsg(result, Status.HDFS_OPERATION_ERROR);
throw new RuntimeException(String.format("upload resource: %s file: %s failed.", name, file.getOriginalFilename()));
}
return result;
}
private boolean checkResourceExists(String alias, int userId, int type ){
List<Resource> resources = resourcesMapper.queryResourceList(alias, userId, type);
if (resources != null && resources.size() > 0) {
return true;
}
return false;
}
/**
* update resource
*
* @param loginUser
* @param type
* @param name
* @param desc
* @return
*/
@Transactional(value = "TransactionManager",rollbackFor = Exception.class)
public Result updateResource(User loginUser,
int resourceId,
String name,
String desc,
ResourceType type) {
Result result = new Result();
// if resource upload startup
if (!PropertyUtils.getResUploadStartupState()){
logger.error("resource upload startup state: {}", PropertyUtils.getResUploadStartupState());
putMsg(result, Status.HDFS_NOT_STARTUP);
return result;
}
Resource resource = resourcesMapper.selectById(resourceId);
String originResourceName = resource.getAlias();
if (resource == null) {
putMsg(result, Status.RESOURCE_NOT_EXIST);
return result;
}
if (loginUser.getId() != resource.getUserId()) {
putMsg(result, Status.USER_NO_OPERATION_PERM);
return result;
}
if (name.equals(resource.getAlias()) && desc.equals(resource.getDesc())) {
putMsg(result, Status.SUCCESS);
return result;
}
//check resource aleady exists
if (!resource.getAlias().equals(name)) {
if (checkResourceExists(name, 0, type.ordinal())) {
logger.error("resource {} already exists, can't recreate", name);
putMsg(result, Status.RESOURCE_EXIST);
return result;
}
}
// updateProcessInstance data
Date now = new Date();
resource.setAlias(name);
resource.setDesc(desc);
resource.setUpdateTime(now);
try {
resourcesMapper.updateById(resource);
putMsg(result, Status.SUCCESS);
Map dataMap = new BeanMap(resource);
Map<String, Object> resultMap = new HashMap<>(5);
for (Object key : dataMap.keySet()) {
if (!Constants.CLASS.equalsIgnoreCase(key.toString())) {
resultMap.put(key.toString(), dataMap.get(key));
}
}
result.setData(resultMap);
} catch (Exception e) {
logger.error(Status.UPDATE_RESOURCE_ERROR.getMsg(), e);
putMsg(result, Status.UPDATE_RESOURCE_ERROR);
return result;
}
// if name unchanged, return directly without moving on HDFS
if (originResourceName.equals(name)) {
return result;
}
// hdfs move
// query tenant by user id
User user = userMapper.queryDetailsById(resource.getUserId());
String tenantCode = tenantMapper.queryById(user.getTenantId()).getTenantCode();
// get file hdfs path
// delete hdfs file by type
String originHdfsFileName = "";
String destHdfsFileName = "";
if (resource.getType().equals(ResourceType.FILE)) {
originHdfsFileName = HadoopUtils.getHdfsFilename(tenantCode, originResourceName);
destHdfsFileName = HadoopUtils.getHdfsFilename(tenantCode, name);
} else if (resource.getType().equals(ResourceType.UDF)) {
originHdfsFileName = HadoopUtils.getHdfsUdfFilename(tenantCode, originResourceName);
destHdfsFileName = HadoopUtils.getHdfsUdfFilename(tenantCode, name);
}
try {
if (HadoopUtils.getInstance().exists(originHdfsFileName)) {
logger.info("hdfs copy {} -> {}", originHdfsFileName, destHdfsFileName);
HadoopUtils.getInstance().copy(originHdfsFileName, destHdfsFileName, true, true);
} else {
logger.error("{} not exist", originHdfsFileName);
putMsg(result,Status.RESOURCE_NOT_EXIST);
}
} catch (Exception e) {
logger.error(MessageFormat.format("hdfs copy {0} -> {1} fail", originHdfsFileName, destHdfsFileName), e);
putMsg(result,Status.HDFS_COPY_FAIL);
}
return result;
}
/**
* query resources list paging
*
* @param loginUser
* @param type
* @param searchVal
* @param pageNo
* @param pageSize
* @return
*/
public Map<String, Object> queryResourceListPaging(User loginUser, ResourceType type, String searchVal, Integer pageNo, Integer pageSize) {
HashMap<String, Object> result = new HashMap<>(5);
Page<Resource> page = new Page(pageNo, pageSize);
int userId = loginUser.getId();
if (isAdmin(loginUser)) {
userId= 0;
}
IPage<Resource> resourceIPage = resourcesMapper.queryResourcePaging(page,
userId, type.ordinal(), searchVal);
PageInfo pageInfo = new PageInfo<Resource>(pageNo, pageSize);
pageInfo.setTotalCount((int)resourceIPage.getTotal());
pageInfo.setLists(resourceIPage.getRecords());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* upload file to hdfs
*
* @param loginUser
* @param name
* @param file
*/
private boolean upload(User loginUser, String name, MultipartFile file, ResourceType type) {
// save to local
String fileSuffix = FileUtils.suffix(file.getOriginalFilename());
String nameSuffix = FileUtils.suffix(name);
// determine file suffix
if (!StringUtils.equals(fileSuffix, nameSuffix)) {
return false;
}
// query tenant
String tenantCode = tenantMapper.queryById(loginUser.getTenantId()).getTenantCode();
// random file name
String localFilename = FileUtils.getUploadFilename(tenantCode, UUID.randomUUID().toString());
// save file to hdfs, and delete original file
String hdfsFilename = "";
String resourcePath = "";
if (type.equals(ResourceType.FILE)) {
hdfsFilename = HadoopUtils.getHdfsFilename(tenantCode, name);
resourcePath = HadoopUtils.getHdfsResDir(tenantCode);
} else if (type.equals(ResourceType.UDF)) {
hdfsFilename = HadoopUtils.getHdfsUdfFilename(tenantCode, name);
resourcePath = HadoopUtils.getHdfsUdfDir(tenantCode);
}
try {
// if tenant dir not exists
if (!HadoopUtils.getInstance().exists(resourcePath)) {
createTenantDirIfNotExists(tenantCode);
}
org.apache.dolphinscheduler.api.utils.FileUtils.copyFile(file, localFilename);
HadoopUtils.getInstance().copyLocalToHdfs(localFilename, hdfsFilename, true, true);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
}
return true;
}
/**
* query resource list
*
* @param loginUser
* @param type
* @return
*/
public Map<String, Object> queryResourceList(User loginUser, ResourceType type) {
Map<String, Object> result = new HashMap<>(5);
List<Resource> resourceList;
int userId = loginUser.getId();
if(isAdmin(loginUser)){
userId = 0;
}
resourceList = resourcesMapper.queryResourceList(null, userId, type.ordinal());
result.put(Constants.DATA_LIST, resourceList);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* delete resource
*
* @param loginUser
* @param resourceId
*/
@Transactional(value = "TransactionManager",rollbackFor = Exception.class)
public Result delete(User loginUser, int resourceId) throws Exception {
Result result = new Result();
// if resource upload startup
if (!PropertyUtils.getResUploadStartupState()){
logger.error("resource upload startup state: {}", PropertyUtils.getResUploadStartupState());
putMsg(result, Status.HDFS_NOT_STARTUP);
return result;
}
//get resource and hdfs path
Resource resource = resourcesMapper.selectById(resourceId);
if (resource == null) {
logger.error("resource file not exist, resource id {}", resourceId);
putMsg(result, Status.RESOURCE_NOT_EXIST);
return result;
}
if (loginUser.getId() != resource.getUserId() && loginUser.getUserType() != UserType.ADMIN_USER) {
putMsg(result, Status.USER_NO_OPERATION_PERM);
return result;
}
String tenantCode = tenantMapper.queryById(loginUser.getTenantId()).getTenantCode();
String hdfsFilename = "";
// delete hdfs file by type
hdfsFilename = getHdfsFileName(resource, tenantCode, hdfsFilename);
//delete data in database
resourcesMapper.deleteById(resourceId);
resourceUserMapper.deleteResourceUser(0, resourceId);
//delete file on hdfs
HadoopUtils.getInstance().delete(hdfsFilename, false);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* verify resource by name and type
* @param name
* @param type
* @param loginUser
* @return
*/
public Result verifyResourceName(String name, ResourceType type,User loginUser) {
Result result = new Result();
putMsg(result, Status.SUCCESS);
if (checkResourceExists(name, 0, type.ordinal())) {
logger.error("resource type:{} name:{} has exist, can't create again.", type, name);
putMsg(result, Status.RESOURCE_EXIST);
} else {
// query tenant
Tenant tenant = tenantMapper.queryById(loginUser.getTenantId());
if(tenant != null){
String tenantCode = tenant.getTenantCode();
try {
String hdfsFilename = getHdfsFileName(type,tenantCode,name);
if(HadoopUtils.getInstance().exists(hdfsFilename)){
logger.error("resource type:{} name:{} has exist in hdfs {}, can't create again.", type, name,hdfsFilename);
putMsg(result, Status.RESOURCE_FILE_EXIST,hdfsFilename);
}
} catch (Exception e) {
logger.error(e.getMessage(),e);
putMsg(result,Status.HDFS_OPERATION_ERROR);
}
}else{
putMsg(result,Status.TENANT_NOT_EXIST);
}
}
return result;
}
/**
* verify resource by name and type
*
* @param name
* @return
*/
public Result verifyResourceName(String name, ResourceType type) {
Result result = new Result();
if (checkResourceExists(name, 0, type.ordinal())) {
logger.error("resource type:{} name:{} has exist, can't create again.", type, name);
putMsg(result, Status.RESOURCE_EXIST);
} else {
putMsg(result, Status.SUCCESS);
}
return result;
}
/**
* view resource file online
*
* @param resourceId
* @return
*/
public Result readResource(int resourceId, int skipLineNum, int limit) {
Result result = new Result();
// if resource upload startup
if (!PropertyUtils.getResUploadStartupState()){
logger.error("resource upload startup state: {}", PropertyUtils.getResUploadStartupState());
putMsg(result, Status.HDFS_NOT_STARTUP);
return result;
}
// get resource by id
Resource resource = resourcesMapper.selectById(resourceId);
if (resource == null) {
logger.error("resouce file not exist, resource id {}", resourceId);
putMsg(result, Status.RESOURCE_NOT_EXIST);
return result;
}
//check preview or not by file suffix
String nameSuffix = FileUtils.suffix(resource.getAlias());
String resourceViewSuffixs = FileUtils.getResourceViewSuffixs();
if (StringUtils.isNotEmpty(resourceViewSuffixs)) {
List<String> strList = Arrays.asList(resourceViewSuffixs.split(","));
if (!strList.contains(nameSuffix)) {
logger.error("resouce suffix {} not support view, resource id {}", nameSuffix, resourceId);
putMsg(result, Status.RESOURCE_SUFFIX_NOT_SUPPORT_VIEW);
return result;
}
}
User user = userMapper.queryDetailsById(resource.getUserId());
String tenantCode = tenantMapper.queryById(user.getTenantId()).getTenantCode();
// hdfs path
String hdfsFileName = HadoopUtils.getHdfsFilename(tenantCode, resource.getAlias());
logger.info("resource hdfs path is {} ", hdfsFileName);
try {
if(HadoopUtils.getInstance().exists(hdfsFileName)){
List<String> content = HadoopUtils.getInstance().catFile(hdfsFileName, skipLineNum, limit);
putMsg(result, Status.SUCCESS);
Map<String, Object> map = new HashMap<>();
map.put(ALIAS, resource.getAlias());
map.put(CONTENT, StringUtils.join(content.toArray(), "\n"));
result.setData(map);
}else{
logger.error("read file {} not exist in hdfs", hdfsFileName);
putMsg(result, Status.RESOURCE_FILE_NOT_EXIST,hdfsFileName);
}
} catch (Exception e) {
logger.error(String.format("Resource %s read failed", hdfsFileName), e);
putMsg(result, Status.HDFS_OPERATION_ERROR);
}
return result;
}
/**
* create resource file online
*
* @param loginUser
* @param type
* @param fileName
* @param fileSuffix
* @param desc
* @param content
* @return
*/
@Transactional(value = "TransactionManager",rollbackFor = Exception.class)
public Result onlineCreateResource(User loginUser, ResourceType type, String fileName, String fileSuffix, String desc, String content) {
Result result = new Result();
// if resource upload startup
if (!PropertyUtils.getResUploadStartupState()){
logger.error("resource upload startup state: {}", PropertyUtils.getResUploadStartupState());
putMsg(result, Status.HDFS_NOT_STARTUP);
return result;
}
//check file suffix
String nameSuffix = fileSuffix.trim();
String resourceViewSuffixs = FileUtils.getResourceViewSuffixs();
if (StringUtils.isNotEmpty(resourceViewSuffixs)) {
List<String> strList = Arrays.asList(resourceViewSuffixs.split(","));
if (!strList.contains(nameSuffix)) {
logger.error("resouce suffix {} not support create", nameSuffix);
putMsg(result, Status.RESOURCE_SUFFIX_NOT_SUPPORT_VIEW);
return result;
}
}
String name = fileName.trim() + "." + nameSuffix;
result = verifyResourceName(name,type,loginUser);
if (!result.getCode().equals(Status.SUCCESS.getCode())) {
return result;
}
// save data
Date now = new Date();
Resource resource = new Resource(name,name,desc,loginUser.getId(),type,content.getBytes().length,now,now);
resourcesMapper.insert(resource);
putMsg(result, Status.SUCCESS);
Map dataMap = new BeanMap(resource);
Map<String, Object> resultMap = new HashMap<>(5);
for (Object key : dataMap.keySet()) {
if (!Constants.CLASS.equalsIgnoreCase(key.toString())) {
resultMap.put(key.toString(), dataMap.get(key));
}
}
result.setData(resultMap);
String tenantCode = tenantMapper.queryById(loginUser.getTenantId()).getTenantCode();
result = uploadContentToHdfs(name, tenantCode, content);
if (!result.getCode().equals(Status.SUCCESS.getCode())) {
throw new RuntimeException(result.getMsg());
}
return result;
}
/**
* updateProcessInstance resource
*
* @param resourceId
* @return
*/
@Transactional(value = "TransactionManager",rollbackFor = Exception.class)
public Result updateResourceContent(int resourceId, String content) {
Result result = new Result();
// if resource upload startup
if (!PropertyUtils.getResUploadStartupState()){
logger.error("resource upload startup state: {}", PropertyUtils.getResUploadStartupState());
putMsg(result, Status.HDFS_NOT_STARTUP);
return result;
}
Resource resource = resourcesMapper.selectById(resourceId);
if (resource == null) {
logger.error("read file not exist, resource id {}", resourceId);
putMsg(result, Status.RESOURCE_NOT_EXIST);
return result;
}
//check can edit by file suffix
String nameSuffix = FileUtils.suffix(resource.getAlias());
String resourceViewSuffixs = FileUtils.getResourceViewSuffixs();
if (StringUtils.isNotEmpty(resourceViewSuffixs)) {
List<String> strList = Arrays.asList(resourceViewSuffixs.split(","));
if (!strList.contains(nameSuffix)) {
logger.error("resouce suffix {} not support updateProcessInstance, resource id {}", nameSuffix, resourceId);
putMsg(result, Status.RESOURCE_SUFFIX_NOT_SUPPORT_VIEW);
return result;
}
}
resource.setSize(content.getBytes().length);
resource.setUpdateTime(new Date());
resourcesMapper.updateById(resource);
User user = userMapper.queryDetailsById(resource.getUserId());
String tenantCode = tenantMapper.queryById(user.getTenantId()).getTenantCode();
result = uploadContentToHdfs(resource.getAlias(), tenantCode, content);
if (!result.getCode().equals(Status.SUCCESS.getCode())) {
throw new RuntimeException(result.getMsg());
}
return result;
}
/**
* @param resourceName
* @param tenantCode
* @param content
* @return
*/
private Result uploadContentToHdfs(String resourceName, String tenantCode, String content) {
Result result = new Result();
String localFilename = "";
String hdfsFileName = "";
try {
localFilename = FileUtils.getUploadFilename(tenantCode, UUID.randomUUID().toString());
if (!FileUtils.writeContent2File(content, localFilename)) {
// write file fail
logger.error("file {} fail, content is {}", localFilename, content);
putMsg(result, Status.RESOURCE_NOT_EXIST);
return result;
}
// get file hdfs path
hdfsFileName = HadoopUtils.getHdfsFilename(tenantCode, resourceName);
String resourcePath = HadoopUtils.getHdfsResDir(tenantCode);
logger.info("resource hdfs path is {} ", hdfsFileName);
HadoopUtils hadoopUtils = HadoopUtils.getInstance();
if (!hadoopUtils.exists(resourcePath)) {
// create if tenant dir not exists
createTenantDirIfNotExists(tenantCode);
}
if (hadoopUtils.exists(hdfsFileName)) {
hadoopUtils.delete(hdfsFileName, false);
}
hadoopUtils.copyLocalToHdfs(localFilename, hdfsFileName, true, true);
} catch (Exception e) {
logger.error(e.getMessage(), e);
result.setCode(Status.HDFS_OPERATION_ERROR.getCode());
result.setMsg(String.format("copy %s to hdfs %s fail", localFilename, hdfsFileName));
return result;
}
putMsg(result, Status.SUCCESS);
return result;
}
/**
* download file
*
* @param resourceId
* @return
*/
public org.springframework.core.io.Resource downloadResource(int resourceId) throws Exception {
// if resource upload startup
if (!PropertyUtils.getResUploadStartupState()){
logger.error("resource upload startup state: {}", PropertyUtils.getResUploadStartupState());
throw new RuntimeException("hdfs not startup");
}
Resource resource = resourcesMapper.selectById(resourceId);
if (resource == null) {
logger.error("download file not exist, resource id {}", resourceId);
return null;
}
User user = userMapper.queryDetailsById(resource.getUserId());
String tenantCode = tenantMapper.queryById(user.getTenantId()).getTenantCode();
String hdfsFileName = "";
hdfsFileName = getHdfsFileName(resource, tenantCode, hdfsFileName);
String localFileName = FileUtils.getDownloadFilename(resource.getAlias());
logger.info("resource hdfs path is {} ", hdfsFileName);
HadoopUtils.getInstance().copyHdfsToLocal(hdfsFileName, localFileName, false, true);
org.springframework.core.io.Resource file = org.apache.dolphinscheduler.api.utils.FileUtils.file2Resource(localFileName);
return file;
}
/**
* unauthorized file
*
* @param loginUser
* @param userId
* @return
*/
public Map<String, Object> unauthorizedFile(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>();
if (checkAdmin(loginUser, result)) {
return result;
}
List<Resource> resourceList = resourcesMapper.queryResourceExceptUserId(userId);
List<Object> list ;
if (resourceList != null && resourceList.size() > 0) {
Set<Resource> resourceSet = new HashSet<>(resourceList);
List<Resource> authedResourceList = resourcesMapper.queryAuthorizedResourceList(userId);
getAuthorizedResourceList(resourceSet, authedResourceList);
list = new ArrayList<>(resourceSet);
}else {
list = new ArrayList<>(0);
}
result.put(Constants.DATA_LIST, list);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* unauthorized udf function
*
* @param loginUser
* @param userId
* @return
*/
public Map<String, Object> unauthorizedUDFFunction(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>(5);
//only admin can operate
if (checkAdmin(loginUser, result)) {
return result;
}
List<UdfFunc> udfFuncList = udfFunctionMapper.queryUdfFuncExceptUserId(userId);
List<UdfFunc> resultList = new ArrayList<>();
Set<UdfFunc> udfFuncSet = null;
if (udfFuncList != null && udfFuncList.size() > 0) {
udfFuncSet = new HashSet<>(udfFuncList);
List<UdfFunc> authedUDFFuncList = udfFunctionMapper.queryAuthedUdfFunc(userId);
getAuthorizedResourceList(udfFuncSet, authedUDFFuncList);
resultList = new ArrayList<>(udfFuncSet);
}
result.put(Constants.DATA_LIST, resultList);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* authorized udf function
*
* @param loginUser
* @param userId
* @return
*/
public Map<String, Object> authorizedUDFFunction(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>();
if (checkAdmin(loginUser, result)) {
return result;
}
List<UdfFunc> udfFuncs = udfFunctionMapper.queryAuthedUdfFunc(userId);
result.put(Constants.DATA_LIST, udfFuncs);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* authorized file
*
* @param loginUser
* @param userId
* @return
*/
public Map<String, Object> authorizedFile(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)){
return result;
}
List<Resource> authedResources = resourcesMapper.queryAuthorizedResourceList(userId);
result.put(Constants.DATA_LIST, authedResources);
putMsg(result,Status.SUCCESS);
return result;
}
/**
* get hdfs file name
*
* @param resource
* @param tenantCode
* @param hdfsFileName
* @return
*/
private String getHdfsFileName(Resource resource, String tenantCode, String hdfsFileName) {
if (resource.getType().equals(ResourceType.FILE)) {
hdfsFileName = HadoopUtils.getHdfsFilename(tenantCode, resource.getAlias());
} else if (resource.getType().equals(ResourceType.UDF)) {
hdfsFileName = HadoopUtils.getHdfsUdfFilename(tenantCode, resource.getAlias());
}
return hdfsFileName;
}
/**
* get hdfs file name
*
* @param resourceType
* @param tenantCode
* @param hdfsFileName
* @return
*/
private String getHdfsFileName(ResourceType resourceType, String tenantCode, String hdfsFileName) {
if (resourceType.equals(ResourceType.FILE)) {
hdfsFileName = HadoopUtils.getHdfsFilename(tenantCode, hdfsFileName);
} else if (resourceType.equals(ResourceType.UDF)) {
hdfsFileName = HadoopUtils.getHdfsUdfFilename(tenantCode, hdfsFileName);
}
return hdfsFileName;
}
/**
* get authorized resource list
*
* @param resourceSet
* @param authedResourceList
*/
private void getAuthorizedResourceList(Set<?> resourceSet, List<?> authedResourceList) {
Set<?> authedResourceSet = null;
if (authedResourceList != null && authedResourceList.size() > 0) {
authedResourceSet = new HashSet<>(authedResourceList);
resourceSet.removeAll(authedResourceSet);
}
}
}

594
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SchedulerService.java

@ -0,0 +1,594 @@
/*
* 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.service;
import org.apache.dolphinscheduler.api.dto.ScheduleParam;
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.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.model.MasterServer;
import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.dao.ProcessDao;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.Schedule;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper;
import org.apache.dolphinscheduler.dao.utils.cron.CronUtils;
import org.apache.dolphinscheduler.server.quartz.ProcessScheduleJob;
import org.apache.dolphinscheduler.server.quartz.QuartzExecutors;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.text.ParseException;
import java.util.*;
/**
* scheduler service
*/
@Service
public class SchedulerService extends BaseService {
private static final Logger logger = LoggerFactory.getLogger(SchedulerService.class);
@Autowired
private ProjectService projectService;
@Autowired
private ExecutorService executorService;
@Autowired
private MonitorService monitorService;
@Autowired
private ProcessDao processDao;
@Autowired
private ScheduleMapper scheduleMapper;
@Autowired
private ProjectMapper projectMapper;
@Autowired
private ProcessDefinitionMapper processDefinitionMapper;
/**
* save schedule
*
* @param loginUser
* @param projectName
* @param processDefineId
* @param schedule
* @param warningType
* @param warningGroupId
* @param failureStrategy
* @return
*/
@Transactional(value = "TransactionManager", rollbackFor = Exception.class)
public Map<String, Object> insertSchedule(User loginUser, String projectName, Integer processDefineId, String schedule, WarningType warningType,
int warningGroupId, FailureStrategy failureStrategy,
String receivers, String receiversCc, Priority processInstancePriority, int workerGroupId) throws IOException {
Map<String, Object> result = new HashMap<String, Object>(5);
Project project = projectMapper.queryByName(projectName);
// check project auth
Map<String, Object> checkResult = checkAuth(loginUser, projectName, project);
if (checkResult != null) {
return checkResult;
}
// check work flow define release state
ProcessDefinition processDefinition = processDao.findProcessDefineById(processDefineId);
result = executorService.checkProcessDefinitionValid(processDefinition, processDefineId);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
Schedule scheduleObj = new Schedule();
Date now = new Date();
scheduleObj.setProjectName(projectName);
scheduleObj.setProcessDefinitionId(processDefinition.getId());
scheduleObj.setProcessDefinitionName(processDefinition.getName());
ScheduleParam scheduleParam = JSONUtils.parseObject(schedule, ScheduleParam.class);
if (DateUtils.differSec(scheduleParam.getStartTime(),scheduleParam.getEndTime()) == 0) {
logger.warn("The start time must not be the same as the end");
putMsg(result,Status.SCHEDULE_START_TIME_END_TIME_SAME);
return result;
}
scheduleObj.setStartTime(scheduleParam.getStartTime());
scheduleObj.setEndTime(scheduleParam.getEndTime());
if (!org.quartz.CronExpression.isValidExpression(scheduleParam.getCrontab())) {
logger.error(scheduleParam.getCrontab() + " verify failure");
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, scheduleParam.getCrontab());
return result;
}
scheduleObj.setCrontab(scheduleParam.getCrontab());
scheduleObj.setWarningType(warningType);
scheduleObj.setWarningGroupId(warningGroupId);
scheduleObj.setFailureStrategy(failureStrategy);
scheduleObj.setCreateTime(now);
scheduleObj.setUpdateTime(now);
scheduleObj.setUserId(loginUser.getId());
scheduleObj.setUserName(loginUser.getUserName());
scheduleObj.setReleaseState(ReleaseState.OFFLINE);
scheduleObj.setProcessInstancePriority(processInstancePriority);
scheduleObj.setWorkerGroupId(workerGroupId);
scheduleMapper.insert(scheduleObj);
/**
* updateProcessInstance receivers and cc by process definition id
*/
processDefinition.setReceivers(receivers);
processDefinition.setReceiversCc(receiversCc);
processDefinitionMapper.updateById(processDefinition);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* updateProcessInstance schedule
*
* @param loginUser
* @param projectName
* @param id
* @param scheduleExpression
* @param warningType
* @param warningGroupId
* @param failureStrategy
* @param scheduleStatus
* @param workerGroupId
* @return
*/
@Transactional(value = "TransactionManager", rollbackFor = Exception.class)
public Map<String, Object> updateSchedule(User loginUser, String projectName, Integer id, String scheduleExpression, WarningType warningType,
int warningGroupId, FailureStrategy failureStrategy,
String receivers, String receiversCc, ReleaseState scheduleStatus,
Priority processInstancePriority, int workerGroupId) throws IOException {
Map<String, Object> result = new HashMap<String, Object>(5);
Project project = projectMapper.queryByName(projectName);
// check project auth
Map<String, Object> checkResult = checkAuth(loginUser, projectName, project);
if (checkResult != null) {
return checkResult;
}
// check schedule exists
Schedule schedule = scheduleMapper.selectById(id);
if (schedule == null) {
putMsg(result, Status.SCHEDULE_CRON_NOT_EXISTS, id);
return result;
}
ProcessDefinition processDefinition = processDao.findProcessDefineById(schedule.getProcessDefinitionId());
if (processDefinition == null) {
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, schedule.getProcessDefinitionId());
return result;
}
/**
* scheduling on-line status forbid modification
*/
if (checkValid(result, schedule.getReleaseState() == ReleaseState.ONLINE, Status.SCHEDULE_CRON_ONLINE_FORBID_UPDATE)) {
return result;
}
Date now = new Date();
// updateProcessInstance param
if (StringUtils.isNotEmpty(scheduleExpression)) {
ScheduleParam scheduleParam = JSONUtils.parseObject(scheduleExpression, ScheduleParam.class);
if (DateUtils.differSec(scheduleParam.getStartTime(),scheduleParam.getEndTime()) == 0) {
logger.warn("The start time must not be the same as the end");
putMsg(result,Status.SCHEDULE_START_TIME_END_TIME_SAME);
return result;
}
schedule.setStartTime(scheduleParam.getStartTime());
schedule.setEndTime(scheduleParam.getEndTime());
if (!org.quartz.CronExpression.isValidExpression(scheduleParam.getCrontab())) {
putMsg(result, Status.SCHEDULE_CRON_CHECK_FAILED, scheduleParam.getCrontab());
return result;
}
schedule.setCrontab(scheduleParam.getCrontab());
}
if (warningType != null) {
schedule.setWarningType(warningType);
}
schedule.setWarningGroupId(warningGroupId);
if (failureStrategy != null) {
schedule.setFailureStrategy(failureStrategy);
}
if (scheduleStatus != null) {
schedule.setReleaseState(scheduleStatus);
}
schedule.setWorkerGroupId(workerGroupId);
schedule.setUpdateTime(now);
schedule.setProcessInstancePriority(processInstancePriority);
scheduleMapper.updateById(schedule);
/**
* updateProcessInstance recipients and cc by process definition ID
*/
processDefinition.setReceivers(receivers);
processDefinition.setReceiversCc(receiversCc);
processDefinitionMapper.updateById(processDefinition);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* set schedule online or offline
*
* @param loginUser
* @param projectName
* @param id
* @param scheduleStatus
* @return
*/
@Transactional(value = "TransactionManager", rollbackFor = Exception.class)
public Map<String, Object> setScheduleState(User loginUser, String projectName, Integer id, ReleaseState scheduleStatus) {
Map<String, Object> result = new HashMap<String, Object>(5);
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = checkAuth(loginUser, projectName, project);
if (checkResult != null) {
return checkResult;
}
// check schedule exists
Schedule scheduleObj = scheduleMapper.selectById(id);
if (scheduleObj == null) {
putMsg(result, Status.SCHEDULE_CRON_NOT_EXISTS, id);
return result;
}
// check schedule release state
if(scheduleObj.getReleaseState() == scheduleStatus){
logger.info("schedule release is already {},needn't to change schedule id: {} from {} to {}",
scheduleObj.getReleaseState(), scheduleObj.getId(), scheduleObj.getReleaseState(), scheduleStatus);
putMsg(result, Status.SCHEDULE_CRON_REALEASE_NEED_NOT_CHANGE, scheduleStatus);
return result;
}
ProcessDefinition processDefinition = processDao.findProcessDefineById(scheduleObj.getProcessDefinitionId());
if (processDefinition == null) {
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, scheduleObj.getProcessDefinitionId());
return result;
}
if(scheduleStatus == ReleaseState.ONLINE){
// check process definition release state
if(processDefinition.getReleaseState() != ReleaseState.ONLINE){
logger.info("not release process definition id: {} , name : {}",
processDefinition.getId(), processDefinition.getName());
putMsg(result, Status.PROCESS_DEFINE_NOT_RELEASE, scheduleObj.getProcessDefinitionId());
return result;
}
// check sub process definition release state
List<Integer> subProcessDefineIds = new ArrayList<>();
processDao.recurseFindSubProcessId(scheduleObj.getProcessDefinitionId(), subProcessDefineIds);
Integer[] idArray = subProcessDefineIds.toArray(new Integer[subProcessDefineIds.size()]);
if (subProcessDefineIds.size() > 0){
List<ProcessDefinition> subProcessDefinitionList =
processDefinitionMapper.queryDefinitionListByIdList(idArray);
if (subProcessDefinitionList != null && subProcessDefinitionList.size() > 0){
for (ProcessDefinition subProcessDefinition : subProcessDefinitionList){
/**
* if there is no online process, exit directly
*/
if (subProcessDefinition.getReleaseState() != ReleaseState.ONLINE){
logger.info("not release process definition id: {} , name : {}",
subProcessDefinition.getId(), subProcessDefinition.getName());
putMsg(result, Status.PROCESS_DEFINE_NOT_RELEASE, subProcessDefinition.getId());
return result;
}
}
}
}
}
// check master server exists
List<MasterServer> masterServers = monitorService.getServerListFromZK(true);
if (masterServers.size() == 0) {
putMsg(result, Status.MASTER_NOT_EXISTS);
}
// set status
scheduleObj.setReleaseState(scheduleStatus);
scheduleMapper.updateById(scheduleObj);
try {
switch (scheduleStatus) {
case ONLINE: {
logger.info("Call master client set schedule online, project id: {}, flow id: {},host: {}, port: {}", project.getId(), processDefinition.getId(), masterServers);
setSchedule(project.getId(), id);
break;
}
case OFFLINE: {
logger.info("Call master client set schedule offline, project id: {}, flow id: {},host: {}, port: {}", project.getId(), processDefinition.getId(), masterServers);
deleteSchedule(project.getId(), id);
break;
}
default: {
putMsg(result, Status.SCHEDULE_STATUS_UNKNOWN, scheduleStatus.toString());
return result;
}
}
} catch (Exception e) {
result.put(Constants.MSG, scheduleStatus == ReleaseState.ONLINE ? "set online failure" : "set offline failure");
throw new RuntimeException(result.get(Constants.MSG).toString());
}
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query schedule
*
* @param loginUser
* @param projectName
* @param processDefineId
* @return
*/
public Map<String, Object> querySchedule(User loginUser, String projectName, Integer processDefineId, String searchVal, Integer pageNo, Integer pageSize) {
HashMap<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
// check project auth
Map<String, Object> checkResult = checkAuth(loginUser, projectName, project);
if (checkResult != null) {
return checkResult;
}
ProcessDefinition processDefinition = processDao.findProcessDefineById(processDefineId);
if (processDefinition == null) {
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, processDefineId);
return result;
}
Page<Schedule> page = new Page(pageNo, pageSize);
IPage<Schedule> scheduleIPage = scheduleMapper.queryByProcessDefineIdPaging(
page, processDefineId, searchVal
);
PageInfo pageInfo = new PageInfo<Schedule>(pageNo, pageSize);
pageInfo.setTotalCount((int)scheduleIPage.getTotal());
pageInfo.setLists(scheduleIPage.getRecords());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query schedule list
*
* @param loginUser
* @param projectName
* @return
*/
public Map<String, Object> queryScheduleList(User loginUser, String projectName) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.queryByName(projectName);
// check project auth
Map<String, Object> checkResult = checkAuth(loginUser, projectName, project);
if (checkResult != null) {
return checkResult;
}
List<Schedule> schedules = scheduleMapper.querySchedulerListByProjectName(projectName);
result.put(Constants.DATA_LIST, schedules);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* set schedule
*
* @see
*/
public void setSchedule(int projectId, int scheduleId) throws RuntimeException{
logger.info("set schedule, project id: {}, scheduleId: {}", projectId, scheduleId);
Schedule schedule = processDao.querySchedule(scheduleId);
if (schedule == null) {
logger.warn("process schedule info not exists");
}
Date startDate = schedule.getStartTime();
Date endDate = schedule.getEndTime();
String jobName = QuartzExecutors.buildJobName(scheduleId);
String jobGroupName = QuartzExecutors.buildJobGroupName(projectId);
Map<String, Object> dataMap = QuartzExecutors.buildDataMap(projectId, scheduleId, schedule);
QuartzExecutors.getInstance().addJob(ProcessScheduleJob.class, jobName, jobGroupName, startDate, endDate,
schedule.getCrontab(), dataMap);
}
/**
* delete schedule
*/
public static void deleteSchedule(int projectId, int scheduleId) throws RuntimeException{
logger.info("delete schedules of project id:{}, schedule id:{}", projectId, scheduleId);
String jobName = QuartzExecutors.buildJobName(scheduleId);
String jobGroupName = QuartzExecutors.buildJobGroupName(projectId);
if(!QuartzExecutors.getInstance().deleteJob(jobName, jobGroupName)){
logger.warn("set offline failure:projectId:{},scheduleId:{}",projectId,scheduleId);
throw new RuntimeException(String.format("set offline failure"));
}
}
/**
* check valid
*
* @param result
* @param bool
* @param status
* @return
*/
private boolean checkValid(Map<String, Object> result, boolean bool, Status status) {
// timeout is valid
if (bool) {
putMsg(result, status);
return true;
}
return false;
}
/**
*
* @param loginUser
* @param projectName
* @param project
* @return
*/
private Map<String, Object> checkAuth(User loginUser, String projectName, Project project) {
// check project auth
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
return null;
}
/**
* delete schedule by id
*
* @param loginUser
* @param projectName
* @param scheduleId
* @return
*/
public Map<String, Object> deleteScheduleById(User loginUser, String projectName, Integer scheduleId) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultEnum = (Status) checkResult.get(Constants.STATUS);
if (resultEnum != Status.SUCCESS) {
return checkResult;
}
Schedule schedule = scheduleMapper.selectById(scheduleId);
if (schedule == null) {
putMsg(result, Status.SCHEDULE_CRON_NOT_EXISTS, scheduleId);
return result;
}
// Determine if the login user is the owner of the schedule
if (loginUser.getId() != schedule.getUserId()) {
putMsg(result, Status.USER_NO_OPERATION_PERM);
return result;
}
// check schedule is already online
if(schedule.getReleaseState() == ReleaseState.ONLINE){
putMsg(result, Status.SCHEDULE_CRON_STATE_ONLINE,schedule.getId());
return result;
}
int delete = scheduleMapper.deleteById(scheduleId);
if (delete > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.DELETE_SCHEDULE_CRON_BY_ID_ERROR);
}
return result;
}
/**
* preview schedule
* @param loginUser
* @param projectName
* @param schedule
* @return
*/
public Map<String,Object> previewSchedule(User loginUser, String projectName, String schedule) {
Map<String, Object> result = new HashMap<>(5);
CronExpression cronExpression;
ScheduleParam scheduleParam = JSONUtils.parseObject(schedule, ScheduleParam.class);
Date now = new Date();
Date startTime = now.after(scheduleParam.getStartTime()) ? now : scheduleParam.getStartTime();
Date endTime = scheduleParam.getEndTime();
try {
cronExpression = CronUtils.parse2CronExpression(scheduleParam.getCrontab());
} catch (ParseException e) {
logger.error(e.getMessage(),e);
putMsg(result,Status.PARSE_TO_CRON_EXPRESSION_ERROR);
return result;
}
List<Date> selfFireDateList = CronUtils.getSelfFireDateList(startTime, endTime,cronExpression);
result.put(Constants.DATA_LIST, selfFireDateList.stream().map(t -> DateUtils.dateToString(t)).limit(org.apache.dolphinscheduler.common.Constants.PREVIEW_SCHEDULE_EXECUTE_COUNT));
putMsg(result, Status.SUCCESS);
return result;
}
}

150
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SessionService.java

@ -0,0 +1,150 @@
/*
* 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.service;
import org.apache.dolphinscheduler.api.controller.BaseController;
import org.apache.dolphinscheduler.api.utils.Constants;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.dao.entity.Session;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.SessionMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* session service
*/
@Service
public class SessionService extends BaseService{
private static final Logger logger = LoggerFactory.getLogger(SessionService.class);
@Autowired
private SessionMapper sessionMapper;
/**
* get user session from request
*
* @param request
* @return
*/
public Session getSession(HttpServletRequest request) {
String sessionId = request.getHeader(Constants.SESSION_ID);
if(StringUtils.isBlank(sessionId)) {
Cookie cookie = getCookie(request, Constants.SESSION_ID);
if (cookie != null) {
sessionId = cookie.getValue();
}
}
if(StringUtils.isBlank(sessionId)) {
return null;
}
String ip = BaseController.getClientIpAddress(request);
logger.debug("get session: {}, ip: {}", sessionId, ip);
return sessionMapper.selectById(sessionId);
}
/**
* create session
*
* @param user
* @param ip
* @return
*/
public String createSession(User user, String ip) {
Session session = null;
// logined
List<Session> sessionList = sessionMapper.queryByUserId(user.getId());
Date now = new Date();
/**
* if you have logged in and are still valid, return directly
*/
if (CollectionUtils.isNotEmpty(sessionList)) {
// is session list greater 1 , delete other ,get one
if (sessionList.size() > 1){
for (int i=1 ; i < sessionList.size();i++){
sessionMapper.deleteById(sessionList.get(i).getId());
}
}
session = sessionList.get(0);
if (now.getTime() - session.getLastLoginTime().getTime() <= Constants.SESSION_TIME_OUT * 1000) {
/**
* updateProcessInstance the latest login time
*/
session.setLastLoginTime(now);
sessionMapper.updateById(session);
return session.getId();
} else {
/**
* session expired, then delete this session first
*/
sessionMapper.deleteById(session.getId());
}
}
// assign new session
session = new Session();
session.setId(UUID.randomUUID().toString());
session.setIp(ip);
session.setUserId(user.getId());
session.setLastLoginTime(now);
sessionMapper.insert(session);
return session.getId();
}
/**
* sign out
* remove ip restrictions
*
* @param ip no use
* @param loginUser
*/
public void signOut(String ip, User loginUser) {
/**
* query session by user id and ip
*/
List<Session> sessionList = sessionMapper.queryByUserId(loginUser.getId());
for (Session session : sessionList){
//delete session
sessionMapper.deleteById(session.getId());
}
}
}

134
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TaskInstanceService.java

@ -0,0 +1,134 @@
/*
* 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.service;
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.common.enums.ExecutionStatus;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.dao.ProcessDao;
import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.TaskInstance;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.TaskInstanceMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.MessageFormat;
import java.util.*;
/**
* task instance service
*/
@Service
public class TaskInstanceService extends BaseService {
private static final Logger logger = LoggerFactory.getLogger(TaskInstanceService.class);
@Autowired
ProjectMapper projectMapper;
@Autowired
ProjectService projectService;
@Autowired
ProcessDao processDao;
@Autowired
TaskInstanceMapper taskInstanceMapper;
/**
* query task list by project, process instance, task name, task start time, task end time, task status, keyword paging
*
* @param loginUser
* @param projectName
* @param processInstanceId
* @param taskName
* @param startDate
* @param endDate
* @param searchVal
* @param stateType
* @param pageNo
* @param pageSize
* @return
*/
public Map<String,Object> queryTaskListPaging(User loginUser, String projectName,
Integer processInstanceId, String taskName, String startDate, String endDate,
String searchVal, ExecutionStatus stateType,String host,
Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(5);
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status status = (Status) checkResult.get(Constants.STATUS);
if (status != Status.SUCCESS) {
return checkResult;
}
int[] statusArray = null;
String statesStr = null;
// filter by status
if(stateType != null){
statusArray = new int[]{stateType.ordinal()};
}
if(statusArray != null){
statesStr = Arrays.toString(statusArray).replace("[", "").replace("]","");
}
Date start = null;
Date end = null;
try {
if(StringUtils.isNotEmpty(startDate)){
start = DateUtils.getScheduleDate(startDate);
}
if(StringUtils.isNotEmpty( endDate)){
end = DateUtils.getScheduleDate(endDate);
}
} catch (Exception e) {
result.put(Constants.STATUS, Status.REQUEST_PARAMS_NOT_VALID_ERROR);
result.put(Constants.MSG, MessageFormat.format(Status.REQUEST_PARAMS_NOT_VALID_ERROR.getMsg(), "startDate,endDate"));
return result;
}
Page<TaskInstance> page = new Page(pageNo, pageSize);
IPage<TaskInstance> taskInstanceIPage = taskInstanceMapper.queryTaskInstanceListPaging(
page, project.getId(), processInstanceId, searchVal, taskName, statesStr, host, start, end
);
PageInfo pageInfo = new PageInfo<ProcessInstance>(pageNo, pageSize);
Set<String> exclusionSet = new HashSet<String>(){{
add(Constants.CLASS);
add("taskJson");
}};
pageInfo.setTotalCount((int)taskInstanceIPage.getTotal());
pageInfo.setLists(CollectionUtils.getListByExclusion(taskInstanceIPage.getRecords(),exclusionSet));
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
}

85
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TaskRecordService.java

@ -0,0 +1,85 @@
/*
* 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.service;
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.dao.TaskRecordDao;
import org.apache.dolphinscheduler.dao.entity.TaskRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.apache.dolphinscheduler.common.Constants.*;
/**
* task record service
*/
@Service
public class TaskRecordService extends BaseService{
private static final Logger logger = LoggerFactory.getLogger(TaskRecordService.class);
/**
* query task record list paging
*
* @param taskName
* @param startDate
* @param taskDate
* @param sourceTable
* @param destTable
* @param endDate
* @param state
* @param pageNo
* @param pageSize
* @return
*/
public Map<String,Object> queryTaskRecordListPaging(boolean isHistory, String taskName, String startDate,
String taskDate, String sourceTable,
String destTable, String endDate,
String state, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(10);
PageInfo pageInfo = new PageInfo<TaskRecord>(pageNo, pageSize);
Map<String, String> map = new HashMap<>(10);
map.put("taskName", taskName);
map.put("taskDate", taskDate);
map.put("state", state);
map.put("sourceTable", sourceTable);
map.put("targetTable", destTable);
map.put("startTime", startDate);
map.put("endTime", endDate);
map.put("offset", pageInfo.getStart().toString());
map.put("pageSize", pageInfo.getPageSize().toString());
String table = isHistory ? TASK_RECORD_TABLE_HISTORY_HIVE_LOG : TASK_RECORD_TABLE_HIVE_LOG;
int count = TaskRecordDao.countTaskRecord(map, table);
List<TaskRecord> recordList = TaskRecordDao.queryAllTaskRecord(map, table);
pageInfo.setTotalCount(count);
pageInfo.setLists(recordList);
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
}

300
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TenantService.java

@ -0,0 +1,300 @@
/*
* 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.service;
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.common.utils.HadoopUtils;
import org.apache.dolphinscheduler.common.utils.PropertyUtils;
import org.apache.dolphinscheduler.dao.entity.Tenant;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.fs.FileStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* tenant service
*/
@Service
public class TenantService extends BaseService{
private static final Logger logger = LoggerFactory.getLogger(TenantService.class);
@Autowired
private TenantMapper tenantMapper;
/**
* create tenant
*
* @param loginUser
* @param tenantCode
* @param tenantName
* @param queueId
* @param desc
* @return
*/
@Transactional(value = "TransactionManager",rollbackFor = Exception.class)
public Map<String,Object> createTenant(User loginUser,
String tenantCode,
String tenantName,
int queueId,
String desc) throws Exception {
Map<String, Object> result = new HashMap<>(5);
result.put(Constants.STATUS, false);
if (checkAdmin(loginUser, result)) {
return result;
}
if (!checkTenant(tenantCode)){
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, tenantCode);
return result;
}
Tenant tenant = new Tenant();
Date now = new Date();
if (!tenantCode.matches("^[0-9a-zA-Z_.-]{1,}$") || tenantCode.startsWith("-") || tenantCode.startsWith(".")){
putMsg(result, Status.VERIFY_TENANT_CODE_ERROR);
return result;
}
tenant.setTenantCode(tenantCode);
tenant.setTenantName(tenantName);
tenant.setQueueId(queueId);
tenant.setDescription(desc);
tenant.setCreateTime(now);
tenant.setUpdateTime(now);
// save
tenantMapper.insert(tenant);
// if hdfs startup
if (PropertyUtils.getResUploadStartupState()){
createTenantDirIfNotExists(tenantCode);
}
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query tenant list paging
*
* @param loginUser
* @param searchVal
* @param pageNo
* @param pageSize
* @return
*/
public Map<String,Object> queryTenantList(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
Page<Tenant> page = new Page(pageNo, pageSize);
IPage<Tenant> tenantIPage = tenantMapper.queryTenantPaging(page, searchVal);
PageInfo<Tenant> pageInfo = new PageInfo<>(pageNo, pageSize);
pageInfo.setTotalCount((int)tenantIPage.getTotal());
pageInfo.setLists(tenantIPage.getRecords());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* updateProcessInstance tenant
*
* @param loginUser
* @param tenantCode
* @param tenantName
* @param queueId
* @param desc
* @return
*/
public Map<String, Object> updateTenant(User loginUser,int id,String tenantCode, String tenantName, int queueId, String desc) throws Exception {
Map<String, Object> result = new HashMap<>(5);
result.put(Constants.STATUS, false);
if (checkAdmin(loginUser, result)) {
return result;
}
Tenant tenant = tenantMapper.queryById(id);
if (tenant == null){
putMsg(result, Status.TENANT_NOT_EXIST);
return result;
}
// updateProcessInstance tenant
/**
* if the tenant code is modified, the original resource needs to be copied to the new tenant.
*/
if (!tenant.getTenantCode().equals(tenantCode)){
if (checkTenant(tenantCode)){
// if hdfs startup
if (PropertyUtils.getResUploadStartupState()){
String resourcePath = HadoopUtils.getHdfsDataBasePath() + "/" + tenantCode + "/resources";
String udfsPath = HadoopUtils.getHdfsUdfDir(tenantCode);
//init hdfs resource
HadoopUtils.getInstance().mkdir(resourcePath);
HadoopUtils.getInstance().mkdir(udfsPath);
}
}else {
putMsg(result, Status.TENANT_CODE_HAS_ALREADY_EXISTS);
return result;
}
}
Date now = new Date();
if (StringUtils.isNotEmpty(tenantCode)){
tenant.setTenantCode(tenantCode);
}
if (StringUtils.isNotEmpty(tenantName)){
tenant.setTenantName(tenantName);
}
if (queueId != 0){
tenant.setQueueId(queueId);
}
tenant.setDescription(desc);
tenant.setUpdateTime(now);
tenantMapper.updateById(tenant);
result.put(Constants.STATUS, Status.SUCCESS);
result.put(Constants.MSG, Status.SUCCESS.getMsg());
return result;
}
/**
* delete tenant
*
* @param loginUser
* @param id
* @return
*/
@Transactional(value = "TransactionManager", rollbackFor = Exception.class)
public Map<String, Object> deleteTenantById(User loginUser, int id) throws Exception {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
Tenant tenant = tenantMapper.queryById(id);
if (tenant == null){
putMsg(result, Status.TENANT_NOT_EXIST);
return result;
}
// if resource upload startup
if (PropertyUtils.getResUploadStartupState()){
String tenantPath = HadoopUtils.getHdfsDataBasePath() + "/" + tenant.getTenantCode();
if (HadoopUtils.getInstance().exists(tenantPath)){
String resourcePath = HadoopUtils.getHdfsResDir(tenant.getTenantCode());
FileStatus[] fileStatus = HadoopUtils.getInstance().listFileStatus(resourcePath);
if (fileStatus.length > 0) {
putMsg(result, Status.HDFS_TERANT_RESOURCES_FILE_EXISTS);
return result;
}
fileStatus = HadoopUtils.getInstance().listFileStatus(HadoopUtils.getHdfsUdfDir(tenant.getTenantCode()));
if (fileStatus.length > 0) {
putMsg(result, Status.HDFS_TERANT_UDFS_FILE_EXISTS);
return result;
}
HadoopUtils.getInstance().delete(tenantPath, true);
}
}
tenantMapper.deleteById(id);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query tenant list
*
* @param loginUser
* @return
*/
public Map<String, Object> queryTenantList(User loginUser) {
Map<String, Object> result = new HashMap<>(5);
List<Tenant> resourceList = tenantMapper.selectList(null);
result.put(Constants.DATA_LIST, resourceList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* verify tenant code
*
* @param tenantCode
* @return
*/
public Result verifyTenantCode(String tenantCode) {
Result result=new Result();
if (checkTenant(tenantCode)) {
logger.error("tenant {} has exist, can't create again.", tenantCode);
putMsg(result, Status.TENANT_NAME_EXIST);
}else{
putMsg(result, Status.SUCCESS);
}
return result;
}
/**
* check tenant exists
*
* @param tenantCode
* @return
*/
private boolean checkTenant(String tenantCode) {
return tenantMapper.queryByTenantCode(tenantCode) == null ? true : false;
}
}

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

Loading…
Cancel
Save