Browse Source

Merge branch 'dev' into dailidong-patch-1-1

pull/3/MERGE
dailidong 4 years ago committed by GitHub
parent
commit
b5c18c2f9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      .github/workflows/ci_backend.yml
  2. 125
      .gitignore
  3. 68
      ambari_plugin/README.md
  4. 164
      ambari_plugin/common-services/DOLPHIN/2.0.0/alerts.json
  5. 143
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-alert.xml
  6. 87
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-application-api.xml
  7. 158
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-common.xml
  8. 467
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-datasource.xml
  9. 123
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-env.xml
  10. 88
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-master.xml
  11. 126
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-quartz.xml
  12. 76
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-worker.xml
  13. 84
      ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-zookeeper.xml
  14. 137
      ambari_plugin/common-services/DOLPHIN/2.0.0/metainfo.xml
  15. 124
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/alerts/alert_dolphin_scheduler_status.py
  16. 61
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_alert_service.py
  17. 70
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_api_service.py
  18. 123
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_env.py
  19. 61
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_logger_service.py
  20. 61
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_master_service.py
  21. 60
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_worker_service.py
  22. 154
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/params.py
  23. 31
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/service_check.py
  24. 23
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/status_params.py
  25. 20
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/application-api.properties.j2
  26. 20
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/common.properties.j2
  27. 20
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/datasource.properties.j2
  28. 116
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/dolphin-daemon.sh.j2
  29. 20
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/master.properties.j2
  30. 20
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/quartz.properties.j2
  31. 20
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/worker.properties.j2
  32. 20
      ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/zookeeper.properties.j2
  33. 26
      ambari_plugin/common-services/DOLPHIN/2.0.0/quicklinks/quicklinks.json
  34. 661
      ambari_plugin/common-services/DOLPHIN/2.0.0/themes/theme.json
  35. 1
      docker/docker-compose.yml
  36. 30
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java
  37. 5
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java
  38. 10
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java
  39. 133
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPlugin.java
  40. 130
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java
  41. 17
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java
  42. 17
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java
  43. 16
      dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java
  44. 2
      dolphinscheduler-alert/src/main/resources/alert.properties
  45. 80
      dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPluginTest.java
  46. 13
      dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java
  47. 10
      dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java
  48. 11
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ExecutorService.java
  49. 1
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SchedulerService.java
  50. 14
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/ZooKeeperState.java
  51. 6
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/ZookeeperMonitor.java
  52. 43
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ExecutorService2Test.java
  53. 5
      dolphinscheduler-common/pom.xml
  54. 7
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java
  55. 107
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/FilePluginManager.java
  56. 154
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginClassLoader.java
  57. 33
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginManager.java
  58. 9
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/HadoopUtils.java
  59. 72
      dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/plugin/FilePluginManagerTest.java
  60. 61
      dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/plugin/PluginClassLoaderTest.java
  61. 12
      dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/HadoopUtilsTest.java
  62. 18
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/ZookeeperRecord.java
  63. 1
      dolphinscheduler-dist/release-docs/LICENSE
  64. 19
      dolphinscheduler-dist/release-docs/licenses/LICENSE-lombok.txt
  65. 52
      dolphinscheduler-plugin-api/pom.xml
  66. 45
      dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/api/AlertPlugin.java
  67. 129
      dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertData.java
  68. 61
      dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertInfo.java
  69. 45
      dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/PluginName.java
  70. 33
      dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/spi/AlertPluginProvider.java
  71. 190
      dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtils.java
  72. 80
      dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/model/AlertDataTest.java
  73. 54
      dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/model/AlertInfoTest.java
  74. 83
      dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtilsTest.java
  75. 8
      dolphinscheduler-plugin-api/src/test/resources/plugin.properties
  76. 16
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/consumer/TaskPriorityQueueConsumer.java
  77. 46
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/runner/MasterTaskExecThread.java
  78. 2
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java
  79. 3
      dolphinscheduler-server/src/main/resources/config/install_config.conf
  80. 262
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/consumer/TaskPriorityQueueConsumerTest.java
  81. 80
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/runner/MasterTaskExecThreadTest.java
  82. 8
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/registry/DependencyConfig.java
  83. 2
      dolphinscheduler-ui/package.json
  84. 7
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue
  85. 7
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/_source/nodeStatus.vue
  86. 9
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/conditions.vue
  87. 24
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
  88. 81
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/index.vue
  89. 47
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue
  90. 68
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/index.vue
  91. 30
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/_source/list.vue
  92. 71
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/index.vue
  93. 13
      dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/list/index.vue
  94. 11
      dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/subdirectory/index.vue
  95. 14
      dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/function/index.vue
  96. 14
      dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/resource/index.vue
  97. 11
      dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/subUdfDirectory/index.vue
  98. 11
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/queue/index.vue
  99. 11
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/tenement/index.vue
  100. 2
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue
  101. Some files were not shown because too many files have changed in this diff Show More

22
.github/workflows/ci_backend.yml

@ -56,21 +56,9 @@ jobs:
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: 1.8 java-version: 1.8
- name: Check license
run: ./mvnw -B apache-rat:check
- name: Compile - name: Compile
run: mvn -B clean compile package -Prelease -Dmaven.test.skip=true run: mvn -B clean compile install -Prelease -Dmaven.test.skip=true
License-check: - name: Check dependency license
runs-on: ubuntu-latest run: tools/dependencies/check-LICENSE.sh
steps:
- uses: actions/checkout@v2
# In the checkout@v2, it doesn't support git submodule. Execute the commands manually.
- name: checkout submodules
shell: bash
run: |
git submodule sync --recursive
git -c protocol.version=2 submodule update --init --force --recursive --depth=1
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Check
run: mvn -B apache-rat:check

125
.gitignore vendored

@ -4,27 +4,24 @@
.zip .zip
.gz .gz
.DS_Store .DS_Store
.idea
.idea/ .idea/
.idea/* dist/
.target all-dependencies.txt
.target/ self-modules.txt
**/**/target/** third-party-dependencies.txt
target/* **/target/
*/target
*/target/*
.settings .settings
.nbproject .nbproject
.classpath .classpath
.project .project
*.iml **/*.iml
*.ipr *.ipr
*.iws *.iws
*.tgz *.tgz
.*.swp .*.swp
.vim .vim
.tmp .tmp
node_modules **/node_modules
npm-debug.log npm-debug.log
.vscode .vscode
logs/* logs/*
@ -41,110 +38,10 @@ dolphinscheduler-alert/logs/
dolphinscheduler-alert/src/main/resources/alert.properties_bak dolphinscheduler-alert/src/main/resources/alert.properties_bak
dolphinscheduler-alert/src/main/resources/logback.xml dolphinscheduler-alert/src/main/resources/logback.xml
dolphinscheduler-server/src/main/resources/logback.xml dolphinscheduler-server/src/main/resources/logback.xml
dolphinscheduler-ui/dist dolphinscheduler-ui/dist/
dolphinscheduler-ui/node dolphinscheduler-ui/node
dolphinscheduler-ui/dist/css/common.16ac5d9.css dolphinscheduler-dao/src/main/resources/dao/data_source.properties
dolphinscheduler-ui/dist/css/home/index.b444b91.css
dolphinscheduler-ui/dist/css/login/index.5866c64.css .mvn/wrapper/*.jar
dolphinscheduler-ui/dist/js/0.ac94e5d.js
dolphinscheduler-ui/dist/js/0.ac94e5d.js.map
dolphinscheduler-ui/dist/js/1.0b043a3.js
dolphinscheduler-ui/dist/js/1.0b043a3.js.map
dolphinscheduler-ui/dist/js/10.1bce3dc.js
dolphinscheduler-ui/dist/js/10.1bce3dc.js.map
dolphinscheduler-ui/dist/js/11.79f04d8.js
dolphinscheduler-ui/dist/js/11.79f04d8.js.map
dolphinscheduler-ui/dist/js/12.420daa5.js
dolphinscheduler-ui/dist/js/12.420daa5.js.map
dolphinscheduler-ui/dist/js/13.e5bae1c.js
dolphinscheduler-ui/dist/js/13.e5bae1c.js.map
dolphinscheduler-ui/dist/js/14.f2a0dca.js
dolphinscheduler-ui/dist/js/14.f2a0dca.js.map
dolphinscheduler-ui/dist/js/15.45373e8.js
dolphinscheduler-ui/dist/js/15.45373e8.js.map
dolphinscheduler-ui/dist/js/16.fecb0fc.js
dolphinscheduler-ui/dist/js/16.fecb0fc.js.map
dolphinscheduler-ui/dist/js/17.84be279.js
dolphinscheduler-ui/dist/js/17.84be279.js.map
dolphinscheduler-ui/dist/js/18.307ea70.js
dolphinscheduler-ui/dist/js/18.307ea70.js.map
dolphinscheduler-ui/dist/js/19.144db9c.js
dolphinscheduler-ui/dist/js/19.144db9c.js.map
dolphinscheduler-ui/dist/js/2.8b4ef29.js
dolphinscheduler-ui/dist/js/2.8b4ef29.js.map
dolphinscheduler-ui/dist/js/20.4c527e9.js
dolphinscheduler-ui/dist/js/20.4c527e9.js.map
dolphinscheduler-ui/dist/js/21.831b2a2.js
dolphinscheduler-ui/dist/js/21.831b2a2.js.map
dolphinscheduler-ui/dist/js/22.2b4bb2a.js
dolphinscheduler-ui/dist/js/22.2b4bb2a.js.map
dolphinscheduler-ui/dist/js/23.81467ef.js
dolphinscheduler-ui/dist/js/23.81467ef.js.map
dolphinscheduler-ui/dist/js/24.54a00e4.js
dolphinscheduler-ui/dist/js/24.54a00e4.js.map
dolphinscheduler-ui/dist/js/25.8d7bd36.js
dolphinscheduler-ui/dist/js/25.8d7bd36.js.map
dolphinscheduler-ui/dist/js/26.2ec5e78.js
dolphinscheduler-ui/dist/js/26.2ec5e78.js.map
dolphinscheduler-ui/dist/js/27.3ab48c2.js
dolphinscheduler-ui/dist/js/27.3ab48c2.js.map
dolphinscheduler-ui/dist/js/28.363088a.js
dolphinscheduler-ui/dist/js/28.363088a.js.map
dolphinscheduler-ui/dist/js/29.6c5853a.js
dolphinscheduler-ui/dist/js/29.6c5853a.js.map
dolphinscheduler-ui/dist/js/3.a0edb5b.js
dolphinscheduler-ui/dist/js/3.a0edb5b.js.map
dolphinscheduler-ui/dist/js/30.940fdd3.js
dolphinscheduler-ui/dist/js/30.940fdd3.js.map
dolphinscheduler-ui/dist/js/31.168a460.js
dolphinscheduler-ui/dist/js/31.168a460.js.map
dolphinscheduler-ui/dist/js/32.8df6594.js
dolphinscheduler-ui/dist/js/32.8df6594.js.map
dolphinscheduler-ui/dist/js/33.4480bbe.js
dolphinscheduler-ui/dist/js/33.4480bbe.js.map
dolphinscheduler-ui/dist/js/34.b407fe1.js
dolphinscheduler-ui/dist/js/34.b407fe1.js.map
dolphinscheduler-ui/dist/js/35.f340b0a.js
dolphinscheduler-ui/dist/js/35.f340b0a.js.map
dolphinscheduler-ui/dist/js/36.8880c2d.js
dolphinscheduler-ui/dist/js/36.8880c2d.js.map
dolphinscheduler-ui/dist/js/37.ea2a25d.js
dolphinscheduler-ui/dist/js/37.ea2a25d.js.map
dolphinscheduler-ui/dist/js/38.98a59ee.js
dolphinscheduler-ui/dist/js/38.98a59ee.js.map
dolphinscheduler-ui/dist/js/39.a5e958a.js
dolphinscheduler-ui/dist/js/39.a5e958a.js.map
dolphinscheduler-ui/dist/js/4.4ca44db.js
dolphinscheduler-ui/dist/js/4.4ca44db.js.map
dolphinscheduler-ui/dist/js/40.e187b1e.js
dolphinscheduler-ui/dist/js/40.e187b1e.js.map
dolphinscheduler-ui/dist/js/41.0e89182.js
dolphinscheduler-ui/dist/js/41.0e89182.js.map
dolphinscheduler-ui/dist/js/42.341047c.js
dolphinscheduler-ui/dist/js/42.341047c.js.map
dolphinscheduler-ui/dist/js/43.27b8228.js
dolphinscheduler-ui/dist/js/43.27b8228.js.map
dolphinscheduler-ui/dist/js/44.e8869bc.js
dolphinscheduler-ui/dist/js/44.e8869bc.js.map
dolphinscheduler-ui/dist/js/45.8d54901.js
dolphinscheduler-ui/dist/js/45.8d54901.js.map
dolphinscheduler-ui/dist/js/5.e1ed7f3.js
dolphinscheduler-ui/dist/js/5.e1ed7f3.js.map
dolphinscheduler-ui/dist/js/6.241ba07.js
dolphinscheduler-ui/dist/js/6.241ba07.js.map
dolphinscheduler-ui/dist/js/7.ab2e297.js
dolphinscheduler-ui/dist/js/7.ab2e297.js.map
dolphinscheduler-ui/dist/js/8.83ff814.js
dolphinscheduler-ui/dist/js/8.83ff814.js.map
dolphinscheduler-ui/dist/js/9.39cb29f.js
dolphinscheduler-ui/dist/js/9.39cb29f.js.map
dolphinscheduler-ui/dist/js/common.733e342.js
dolphinscheduler-ui/dist/js/common.733e342.js.map
dolphinscheduler-ui/dist/js/home/index.78a5d12.js
dolphinscheduler-ui/dist/js/home/index.78a5d12.js.map
dolphinscheduler-ui/dist/js/login/index.291b8e3.js
dolphinscheduler-ui/dist/js/login/index.291b8e3.js.map
dolphinscheduler-ui/dist/lib/external/
/dolphinscheduler-dao/src/main/resources/dao/data_source.properties
!/zookeeper_data/ !/zookeeper_data/

68
ambari_plugin/README.md

@ -0,0 +1,68 @@
### Dolphin Scheduler的Ambari插件使用说明
##### 备注
1. 本文档适用于对Ambari中基本了解的用户
2. 本文档是对已安装Ambari服务添加Dolphin Scheduler(1.3.0版本)服务的说明
##### 一 安装准备
1. 准备RPM包
- 在源码dolphinscheduler-dist目录下执行命令```mvn -U clean install rpm:attached-rpm -Prpmbuild -Dmaven.test.skip=true -X```即可生成(在目录 dolphinscheduler-dist/target/rpm/apache-dolphinscheduler-incubating/RPMS/noarch 下)
2. 创建DS的安装用户--权限
3. 初始化数据库信息
```
-- 创建Dolphin Scheduler的数据库:dolphinscheduler
CREATE DATABASE dolphinscheduler DEFAULT CHARACTER SET utf8 DEFAULT COLLATE
utf8_general_ci;
-- 初始化dolphinscheduler数据库的用户和密码,并分配权限
-- 替换下面sql语句中的{user}为dolphinscheduler数据库的用户
GRANT ALL PRIVILEGES ON dolphinscheduler.* TO '{user}'@'%' IDENTIFIED BY '{password}';
GRANT ALL PRIVILEGES ON dolphinscheduler.* TO '{user}'@'localhost' IDENTIFIED BY
'{password}';
flush privileges;
```
##### 二 Ambari安装Dolphin Scheduler
1. Ambari界面安装Dolphin Scheduler
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_001.png)
2. 选择Dolphin Scheduler的Master安装的节点
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_002.png)
3. 配置Dolphin Scheduler的Worker、Api、Logger、Alert安装的节点
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_003.png)
4. 设置Dolphin Scheduler服务的安装用户(**步骤一中创建的**)及所属的用户组
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_004.png)
5. 配置数据库的信息(和步骤一中初始化数据库中一致)
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_005.png)
6. 配置其它的信息--如果需要的话
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_006.png)
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_007.png)
7. 正常执行接下来的步骤
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_008.png)
8. 安装成功后的界面
![](https://github.com/apache/incubator-dolphinscheduler-website/blob/master/img/ambari-plugin/DS2_AMBARI_009.png)

164
ambari_plugin/common-services/DOLPHIN/2.0.0/alerts.json

@ -1,164 +0,0 @@
{
"DOLPHIN": {
"service": [],
"DOLPHIN_API": [
{
"name": "dolphin_api_port_check",
"label": "dolphin_api_port_check",
"description": "dolphin_api_port_check.",
"interval": 10,
"scope": "ANY",
"source": {
"type": "PORT",
"uri": "{{dolphin-application-api/server.port}}",
"default_port": 12345,
"reporting": {
"ok": {
"text": "TCP OK - {0:.3f}s response on port {1}"
},
"warning": {
"text": "TCP OK - {0:.3f}s response on port {1}",
"value": 1.5
},
"critical": {
"text": "Connection failed: {0} to {1}:{2}",
"value": 5.0
}
}
}
}
],
"DOLPHIN_MASTER": [
{
"name": "DOLPHIN_MASTER_CHECK",
"label": "check dolphin scheduler master status",
"description": "",
"interval":10,
"scope": "HOST",
"enabled": true,
"source": {
"type": "SCRIPT",
"path": "DOLPHIN/2.0.0/package/alerts/alert_dolphin_scheduler_status.py",
"parameters": [
{
"name": "connection.timeout",
"display_name": "Connection Timeout",
"value": 5.0,
"type": "NUMERIC",
"description": "The maximum time before this alert is considered to be CRITICAL",
"units": "seconds",
"threshold": "CRITICAL"
},
{
"name": "alertName",
"display_name": "alertName",
"value": "DOLPHIN_MASTER",
"type": "STRING",
"description": "alert name"
}
]
}
}
],
"DOLPHIN_WORKER": [
{
"name": "DOLPHIN_WORKER_CHECK",
"label": "check dolphin scheduler worker status",
"description": "",
"interval":10,
"scope": "HOST",
"enabled": true,
"source": {
"type": "SCRIPT",
"path": "DOLPHIN/2.0.0/package/alerts/alert_dolphin_scheduler_status.py",
"parameters": [
{
"name": "connection.timeout",
"display_name": "Connection Timeout",
"value": 5.0,
"type": "NUMERIC",
"description": "The maximum time before this alert is considered to be CRITICAL",
"units": "seconds",
"threshold": "CRITICAL"
},
{
"name": "alertName",
"display_name": "alertName",
"value": "DOLPHIN_WORKER",
"type": "STRING",
"description": "alert name"
}
]
}
}
],
"DOLPHIN_ALERT": [
{
"name": "DOLPHIN_DOLPHIN_ALERT_CHECK",
"label": "check dolphin scheduler alert status",
"description": "",
"interval":10,
"scope": "HOST",
"enabled": true,
"source": {
"type": "SCRIPT",
"path": "DOLPHIN/2.0.0/package/alerts/alert_dolphin_scheduler_status.py",
"parameters": [
{
"name": "connection.timeout",
"display_name": "Connection Timeout",
"value": 5.0,
"type": "NUMERIC",
"description": "The maximum time before this alert is considered to be CRITICAL",
"units": "seconds",
"threshold": "CRITICAL"
},
{
"name": "alertName",
"display_name": "alertName",
"value": "DOLPHIN_ALERT",
"type": "STRING",
"description": "alert name"
}
]
}
}
],
"DOLPHIN_ALERT": [
{
"name": "DOLPHIN_DOLPHIN_LOGGER_CHECK",
"label": "check dolphin scheduler alert status",
"description": "",
"interval":10,
"scope": "HOST",
"enabled": true,
"source": {
"type": "SCRIPT",
"path": "DOLPHIN/2.0.0/package/alerts/alert_dolphin_scheduler_status.py",
"parameters": [
{
"name": "connection.timeout",
"display_name": "Connection Timeout",
"value": 5.0,
"type": "NUMERIC",
"description": "The maximum time before this alert is considered to be CRITICAL",
"units": "seconds",
"threshold": "CRITICAL"
},
{
"name": "alertName",
"display_name": "alertName",
"value": "DOLPHIN_LOGGER",
"type": "STRING",
"description": "alert name"
}
]
}
}
]
}
}

143
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-alert.xml

@ -1,143 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>alert.type</name>
<value>EMAIL</value>
<description>alert type is EMAIL/SMS</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>alert.template</name>
<value>html</value>
<description>alter msg template, default is html template</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.protocol</name>
<value>SMTP</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.server.host</name>
<value>xxx.xxx.com</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.server.port</name>
<value>25</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.sender</name>
<value>admin</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.user</name>
<value>admin</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.passwd</name>
<value>000000</value>
<description></description>
<property-type>PASSWORD</property-type>
<value-attributes>
<type>password</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.smtp.starttls.enable</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.smtp.ssl.enable</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mail.smtp.ssl.trust</name>
<value>xxx.xxx.com</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>enterprise.wechat.enable</name>
<value>false</value>
<description></description>
<value-attributes>
<type>value-list</type>
<entries>
<entry>
<value>true</value>
<label>Enabled</label>
</entry>
<entry>
<value>false</value>
<label>Disabled</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>enterprise.wechat.corp.id</name>
<value>wechatId</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>enterprise.wechat.secret</name>
<value>secret</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>enterprise.wechat.agent.id</name>
<value>agentId</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>enterprise.wechat.users</name>
<value>wechatUsers</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
</configuration>

87
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-application-api.xml

@ -1,87 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>server.port</name>
<value>12345</value>
<description>
server port
</description>
<value-attributes>
<type>int</type>
</value-attributes>
</property>
<property>
<name>server.servlet.session.timeout</name>
<value>7200</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>
</description>
</property>
<property>
<name>server.servlet.context-path</name>
<value>/dolphinscheduler/</value>
<description>
</description>
</property>
<property>
<name>spring.servlet.multipart.max-file-size</name>
<value>1024</value>
<value-attributes>
<unit>MB</unit>
<type>int</type>
</value-attributes>
<description>
</description>
</property>
<property>
<name>spring.servlet.multipart.max-request-size</name>
<value>1024</value>
<value-attributes>
<unit>MB</unit>
<type>int</type>
</value-attributes>
<description>
</description>
</property>
<property>
<name>server.jetty.max-http-post-size</name>
<value>5000000</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>
</description>
</property>
<property>
<name>spring.messages.encoding</name>
<value>UTF-8</value>
<description></description>
</property>
<property>
<name>spring.messages.basename</name>
<value>i18n/messages</value>
<description></description>
</property>
<property>
<name>security.authentication.type</name>
<value>PASSWORD</value>
<description></description>
</property>
</configuration>

158
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-common.xml

@ -1,158 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>resource.storage.type</name>
<display-name>Choose Resource Upload Startup Type</display-name>
<description>
Resource upload startup type : HDFS,S3,NONE
</description>
<value>NONE</value>
<value-attributes>
<type>value-list</type>
<entries>
<entry>
<value>HDFS</value>
<label>HDFS</label>
</entry>
<entry>
<value>S3</value>
<label>S3</label>
</entry>
<entry>
<value>NONE</value>
<label>NONE</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>resource.upload.path</name>
<value>/dolphinscheduler</value>
<description>
resource store on HDFS/S3 path, resource file will store to this hadoop hdfs path, self configuration, please make sure the directory exists on hdfs and have read write permissions。"/dolphinscheduler" is recommended
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>data.basedir.path</name>
<value>/tmp/dolphinscheduler</value>
<description>
user data local directory path, please make sure the directory exists and have read write permissions
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>hadoop.security.authentication.startup.state</name>
<value>false</value>
<value-attributes>
<type>value-list</type>
<entries>
<entry>
<value>true</value>
<label>Enabled</label>
</entry>
<entry>
<value>false</value>
<label>Disabled</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>
<description>whether kerberos starts</description>
</property>
<property>
<name>java.security.krb5.conf.path</name>
<value>/opt/krb5.conf</value>
<description>
java.security.krb5.conf path
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>login.user.keytab.username</name>
<value>hdfs-mycluster@ESZ.COM</value>
<description>
LoginUserFromKeytab user
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>login.user.keytab.path</name>
<value>/opt/hdfs.headless.keytab</value>
<description>
LoginUserFromKeytab path
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>resource.view.suffixs</name>
<value>txt,log,sh,conf,cfg,py,java,sql,hql,xml,properties</value>
<description></description>
</property>
<property>
<name>hdfs.root.user</name>
<value>hdfs</value>
<description>
Users who have permission to create directories under the HDFS root path
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster:8020</value>
<description>
HA or single namenode,
If namenode ha needs to copy core-site.xml and hdfs-site.xml to the conf directory,
support s3,for example : s3a://dolphinscheduler
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>fs.s3a.endpoint</name>
<value>http://host:9010</value>
<description>
s3 need,s3 endpoint
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>fs.s3a.access.key</name>
<value>A3DXS30FO22544RE</value>
<description>
s3 need,s3 access key
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>fs.s3a.secret.key</name>
<value>OloCLq3n+8+sdPHUhJ21XrSxTC+JK</value>
<description>
s3 need,s3 secret key
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>kerberos.expire.time</name>
<value>7</value>
<description></description>
</property>
</configuration>

467
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-datasource.xml

@ -1,467 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>spring.datasource.initialSize</name>
<value>5</value>
<description>
Init connection number
</description>
<value-attributes>
<type>int</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.minIdle</name>
<value>5</value>
<description>
Min connection number
</description>
<value-attributes>
<type>int</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.maxActive</name>
<value>50</value>
<description>
Max connection number
</description>
<value-attributes>
<type>int</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.maxWait</name>
<value>60000</value>
<description>
Max wait time for get a connection in milliseconds.
If configuring maxWait, fair locks are enabled by default and concurrency efficiency decreases.
If necessary, unfair locks can be used by configuring the useUnfairLock attribute to true.
</description>
<value-attributes>
<type>int</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.timeBetweenEvictionRunsMillis</name>
<value>60000</value>
<description>
Milliseconds for check to close free connections
</description>
<value-attributes>
<type>int</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.timeBetweenConnectErrorMillis</name>
<value>60000</value>
<description>
The Destroy thread detects the connection interval and closes the physical connection in milliseconds
if the connection idle time is greater than or equal to minEvictableIdleTimeMillis.
</description>
<value-attributes>
<type>int</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.minEvictableIdleTimeMillis</name>
<value>300000</value>
<description>
The longest time a connection remains idle without being evicted, in milliseconds
</description>
<value-attributes>
<type>int</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.validationQuery</name>
<value>SELECT 1</value>
<description>
The SQL used to check whether the connection is valid requires a query statement.
If validation Query is null, testOnBorrow, testOnReturn, and testWhileIdle will not work.
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.validationQueryTimeout</name>
<value>3</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>
Check whether the connection is valid for timeout, in seconds
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.testWhileIdle</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description>
When applying for a connection,
if it is detected that the connection is idle longer than time Between Eviction Runs Millis,
validation Query is performed to check whether the connection is valid
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.testOnBorrow</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description>
Execute validation to check if the connection is valid when applying for a connection
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.testOnReturn</name>
<value>false</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description>
Execute validation to check if the connection is valid when the connection is returned
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.defaultAutoCommit</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description>
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.keepAlive</name>
<value>false</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description>
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.poolPreparedStatements</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description>
Open PSCache, specify count PSCache for every connection
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.maxPoolPreparedStatementPerConnectionSize</name>
<value>20</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.spring.datasource.filters</name>
<value>stat,wall,log4j</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>spring.datasource.connectionProperties</name>
<value>druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.mapper-locations</name>
<value>classpath*:/org.apache.dolphinscheduler.dao.mapper/*.xml</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.typeEnumsPackage</name>
<value>org.apache.dolphinscheduler.*.enums</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.typeAliasesPackage</name>
<value>org.apache.dolphinscheduler.dao.entity</value>
<description>
Entity scan, where multiple packages are separated by a comma or semicolon
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.global-config.db-config.id-type</name>
<value>AUTO</value>
<value-attributes>
<type>value-list</type>
<entries>
<entry>
<value>AUTO</value>
<label>AUTO</label>
</entry>
<entry>
<value>INPUT</value>
<label>INPUT</label>
</entry>
<entry>
<value>ID_WORKER</value>
<label>ID_WORKER</label>
</entry>
<entry>
<value>UUID</value>
<label>UUID</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>
<description>
Primary key type AUTO:" database ID AUTO ",
INPUT:" user INPUT ID",
ID_WORKER:" global unique ID (numeric type unique ID)",
UUID:" global unique ID UUID";
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.global-config.db-config.field-strategy</name>
<value>NOT_NULL</value>
<value-attributes>
<type>value-list</type>
<entries>
<entry>
<value>IGNORED</value>
<label>IGNORED</label>
</entry>
<entry>
<value>NOT_NULL</value>
<label>NOT_NULL</label>
</entry>
<entry>
<value>NOT_EMPTY</value>
<label>NOT_EMPTY</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>
<description>
Field policy IGNORED:" ignore judgment ",
NOT_NULL:" not NULL judgment "),
NOT_EMPTY:" not NULL judgment"
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.global-config.db-config.column-underline</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.global-config.db-config.logic-delete-value</name>
<value>1</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.global-config.db-config.logic-not-delete-value</name>
<value>0</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.global-config.db-config.banner</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.configuration.map-underscore-to-camel-case</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.configuration.cache-enabled</name>
<value>false</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.configuration.call-setters-on-nulls</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>mybatis-plus.configuration.jdbc-type-for-null</name>
<value>null</value>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.exec.threads</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.exec.task.num</name>
<value>20</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.heartbeat.interval</name>
<value>10</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.task.commit.retryTimes</name>
<value>5</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.task.commit.interval</name>
<value>1000</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.max.cpuload.avg</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.reserved.memory</name>
<value>0.1</value>
<value-attributes>
<type>float</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.exec.threads</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.heartbeat.interval</name>
<value>10</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.fetch.task.num</name>
<value>3</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.max.cpuload.avg</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.reserved.memory</name>
<value>0.1</value>
<value-attributes>
<type>float</type>
</value-attributes>
<description></description>
<on-ambari-upgrade add="true"/>
</property>
</configuration>

123
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-env.xml

@ -1,123 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>dolphin.database.type</name>
<value>mysql</value>
<description>Dolphin Scheduler DataBase Type Which Is Select</description>
<display-name>Dolphin Database Type</display-name>
<value-attributes>
<type>value-list</type>
<entries>
<entry>
<value>mysql</value>
<label>Mysql</label>
</entry>
<entry>
<value>postgresql</value>
<label>Postgresql</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>dolphin.database.host</name>
<value></value>
<display-name>Dolphin Database Host</display-name>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>dolphin.database.port</name>
<value></value>
<display-name>Dolphin Database Port</display-name>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>dolphin.database.username</name>
<value></value>
<display-name>Dolphin Database Username</display-name>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>dolphin.database.password</name>
<value></value>
<display-name>Dolphin Database Password</display-name>
<property-type>PASSWORD</property-type>
<value-attributes>
<type>password</type>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>dolphin.user</name>
<value></value>
<description>Which user to install and admin dolphin scheduler</description>
<display-name>Deploy User</display-name>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>dolphin.group</name>
<value></value>
<description>Which user to install and admin dolphin scheduler</description>
<display-name>Deploy Group</display-name>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>dolphinscheduler-env-content</name>
<display-name>Dolphinscheduler Env template</display-name>
<description>This is the jinja template for dolphinscheduler.env.sh file</description>
<value>#
# 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.
#
export HADOOP_HOME=/opt/soft/hadoop
export HADOOP_CONF_DIR=/opt/soft/hadoop/etc/hadoop
export SPARK_HOME1=/opt/soft/spark1
export SPARK_HOME2=/opt/soft/spark2
export PYTHON_HOME=/opt/soft/python
export JAVA_HOME=/opt/soft/java
export HIVE_HOME=/opt/soft/hive
export FLINK_HOME=/opt/soft/flink</value>
<value-attributes>
<type>content</type>
<empty-value-valid>false</empty-value-valid>
<show-property-name>false</show-property-name>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
</configuration>

88
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-master.xml

@ -1,88 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>master.exec.threads</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>master execute thread num</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.exec.task.num</name>
<value>20</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>master execute task number in parallel</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.heartbeat.interval</name>
<value>10</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>master heartbeat interval</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.task.commit.retryTimes</name>
<value>5</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>master commit task retry times</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.task.commit.interval</name>
<value>1000</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>master commit task interval</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.max.cpuload.avg</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>only less than cpu avg load, master server can work. default value : the number of cpu cores * 2</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.reserved.memory</name>
<value>0.3</value>
<description>only larger than reserved memory, master server can work. default value : physical memory * 1/10, unit is G.</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>master.listen.port</name>
<value>5678</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>master listen port</description>
<on-ambari-upgrade add="true"/>
</property>
</configuration>

126
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-quartz.xml

@ -1,126 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>org.quartz.scheduler.instanceName</name>
<value>DolphinScheduler</value>
<description></description>
</property>
<property>
<!-- 列举枚举值 -->
<name>org.quartz.scheduler.instanceId</name>
<value>AUTO</value>
<description></description>
</property>
<property>
<name>org.quartz.scheduler.makeSchedulerThreadDaemon</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.jobStore.useProperties</name>
<value>false</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.threadPool.class</name>
<value>org.quartz.simpl.SimpleThreadPool</value>
<description></description>
</property>
<property>
<name>org.quartz.threadPool.makeThreadsDaemons</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.threadPool.threadCount</name>
<value>25</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.threadPool.threadPriority</name>
<value>5</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.jobStore.class</name>
<value>org.quartz.impl.jdbcjobstore.JobStoreTX</value>
<description></description>
</property>
<property>
<name>org.quartz.jobStore.tablePrefix</name>
<value>QRTZ_</value>
<description></description>
</property>
<property>
<name>org.quartz.jobStore.isClustered</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.jobStore.misfireThreshold</name>
<value>60000</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.jobStore.clusterCheckinInterval</name>
<value>5000</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.jobStore.acquireTriggersWithinLock</name>
<value>true</value>
<value-attributes>
<type>boolean</type>
</value-attributes>
<description></description>
</property>
<property>
<name>org.quartz.jobStore.dataSource</name>
<value>myDs</value>
<description></description>
</property>
<property>
<name>org.quartz.dataSource.myDs.connectionProvider.class</name>
<value>org.apache.dolphinscheduler.service.quartz.DruidConnectionProvider</value>
<description></description>
</property>
</configuration>

76
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-worker.xml

@ -1,76 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>worker.exec.threads</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>worker execute thread num</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.heartbeat.interval</name>
<value>10</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>worker heartbeat interval</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.fetch.task.num</name>
<value>3</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>submit the number of tasks at a time</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.max.cpuload.avg</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>only less than cpu avg load, worker server can work. default value : the number of cpu cores * 2</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.reserved.memory</name>
<value>0.3</value>
<description>only larger than reserved memory, worker server can work. default value : physical memory * 1/10, unit is G.</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.listen.port</name>
<value>1234</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>worker listen port</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>worker.group</name>
<value>default</value>
<description>default worker group</description>
<on-ambari-upgrade add="true"/>
</property>
</configuration>

84
ambari_plugin/common-services/DOLPHIN/2.0.0/configuration/dolphin-zookeeper.xml

@ -1,84 +0,0 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<property>
<name>dolphinscheduler.queue.impl</name>
<value>zookeeper</value>
<description>
Task queue implementation, default "zookeeper"
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>zookeeper.dolphinscheduler.root</name>
<value>/dolphinscheduler</value>
<description>
dolphinscheduler root directory
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>zookeeper.session.timeout</name>
<value>300</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>zookeeper.connection.timeout</name>
<value>300</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>zookeeper.retry.base.sleep</name>
<value>100</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>zookeeper.retry.max.sleep</name>
<value>30000</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>zookeeper.retry.maxtime</name>
<value>5</value>
<value-attributes>
<type>int</type>
</value-attributes>
<description>
</description>
<on-ambari-upgrade add="true"/>
</property>
</configuration>

137
ambari_plugin/common-services/DOLPHIN/2.0.0/metainfo.xml

@ -1,137 +0,0 @@
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<metainfo>
<schemaVersion>2.0</schemaVersion>
<services>
<service>
<name>DOLPHIN</name>
<displayName>Dolphin Scheduler</displayName>
<comment>分布式易扩展的可视化DAG工作流任务调度系统</comment>
<version>2.0.0</version>
<components>
<component>
<name>DOLPHIN_MASTER</name>
<displayName>DS Master</displayName>
<category>MASTER</category>
<cardinality>1+</cardinality>
<commandScript>
<script>scripts/dolphin_master_service.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</component>
<component>
<name>DOLPHIN_LOGGER</name>
<displayName>DS Logger</displayName>
<category>SLAVE</category>
<cardinality>1+</cardinality>
<commandScript>
<script>scripts/dolphin_logger_service.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</component>
<component>
<name>DOLPHIN_WORKER</name>
<displayName>DS Worker</displayName>
<category>SLAVE</category>
<cardinality>1+</cardinality>
<dependencies>
<dependency>
<name>DOLPHIN/DOLPHIN_LOGGER</name>
<scope>host</scope>
<auto-deploy>
<enabled>true</enabled>
</auto-deploy>
</dependency>
</dependencies>
<commandScript>
<script>scripts/dolphin_worker_service.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</component>
<component>
<name>DOLPHIN_ALERT</name>
<displayName>DS Alert</displayName>
<category>SLAVE</category>
<cardinality>1</cardinality>
<commandScript>
<script>scripts/dolphin_alert_service.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</component>
<component>
<name>DOLPHIN_API</name>
<displayName>DS_Api</displayName>
<category>SLAVE</category>
<cardinality>1</cardinality>
<commandScript>
<script>scripts/dolphin_api_service.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</component>
</components>
<requiredServices>
<service>ZOOKEEPER</service>
</requiredServices>
<osSpecifics>
<osSpecific>
<osFamily>any</osFamily>
<packages>
<package>
<name>apache-dolphinscheduler-incubating-1.2.1*</name>
</package>
</packages>
</osSpecific>
</osSpecifics>
<configuration-dependencies>
<config-type>dolphin-alert</config-type>
<config-type>dolphin-app-api</config-type>
<config-type>dolphin-app-dao</config-type>
<config-type>dolphin-common</config-type>
<config-type>dolphin-env</config-type>
<config-type>dolphin-quartz</config-type>
</configuration-dependencies>
<themes>
<theme>
<fileName>theme.json</fileName>
<default>true</default>
</theme>
</themes>
<quickLinksConfigurations-dir>quicklinks</quickLinksConfigurations-dir>
<quickLinksConfigurations>
<quickLinksConfiguration>
<fileName>quicklinks.json</fileName>
<default>true</default>
</quickLinksConfiguration>
</quickLinksConfigurations>
</service>
</services>
</metainfo>

124
ambari_plugin/common-services/DOLPHIN/2.0.0/package/alerts/alert_dolphin_scheduler_status.py

@ -1,124 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import socket
import urllib2
import os
import logging
import ambari_simplejson as json
from resource_management.libraries.script.script import Script
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
logger = logging.getLogger('ambari_alerts')
config = Script.get_config()
def get_tokens():
"""
Returns a tuple of tokens in the format {{site/property}} that will be used
to build the dictionary passed into execute
:rtype tuple
"""
def get_info(url, connection_timeout):
response = None
try:
response = urllib2.urlopen(url, timeout=connection_timeout)
json_data = response.read()
return json_data
finally:
if response is not None:
try:
response.close()
except:
pass
def execute(configurations={}, parameters={}, host_name=None):
"""
Returns a tuple containing the result code and a pre-formatted result label
Keyword arguments:
configurations : a mapping of configuration key to value
parameters : a mapping of script parameter key to value
host_name : the name of this host where the alert is running
:type configurations dict
:type parameters dict
:type host_name str
"""
alert_name = parameters['alertName']
dolphin_pidfile_dir = "/opt/soft/run/dolphinscheduler"
pid = "0"
from resource_management.core import sudo
is_running = True
pid_file_path = ""
if alert_name == 'DOLPHIN_MASTER':
pid_file_path = dolphin_pidfile_dir + "/master-server.pid"
elif alert_name == 'DOLPHIN_WORKER':
pid_file_path = dolphin_pidfile_dir + "/worker-server.pid"
elif alert_name == 'DOLPHIN_ALERT':
pid_file_path = dolphin_pidfile_dir + "/alert-server.pid"
elif alert_name == 'DOLPHIN_LOGGER':
pid_file_path = dolphin_pidfile_dir + "/logger-server.pid"
elif alert_name == 'DOLPHIN_API':
pid_file_path = dolphin_pidfile_dir + "/api-server.pid"
if not pid_file_path or not os.path.isfile(pid_file_path):
is_running = False
try:
pid = int(sudo.read_file(pid_file_path))
except:
is_running = False
try:
# Kill will not actually kill the process
# From the doc:
# If sig is 0, then no signal is sent, but error checking is still
# performed; this can be used to check for the existence of a
# process ID or process group ID.
sudo.kill(pid, 0)
except OSError:
is_running = False
if host_name is None:
host_name = socket.getfqdn()
if not is_running:
result_code = "CRITICAL"
else:
result_code = "OK"
label = "The comment {0} of DOLPHIN_SCHEDULER on {1} is {2}".format(alert_name, host_name, result_code)
return ((result_code, [label]))
if __name__ == "__main__":
pass

61
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_alert_service.py

@ -1,61 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import time
from resource_management import *
from dolphin_env import dolphin_env
class DolphinAlertService(Script):
def install(self, env):
import params
env.set_params(params)
self.install_packages(env)
Execute(('chmod', '-R', '777', params.dolphin_home), user=params.dolphin_user, sudo=True)
def configure(self, env):
import params
params.pika_slave = True
env.set_params(params)
dolphin_env()
def start(self, env):
import params
env.set_params(params)
self.configure(env)
no_op_test = format("ls {dolphin_pidfile_dir}/alert-server.pid >/dev/null 2>&1 && ps `cat {dolphin_pidfile_dir}/alert-server.pid` | grep `cat {dolphin_pidfile_dir}/alert-server.pid` >/dev/null 2>&1")
start_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh start alert-server")
Execute(start_cmd, user=params.dolphin_user, not_if=no_op_test)
def stop(self, env):
import params
env.set_params(params)
stop_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh stop alert-server")
Execute(stop_cmd, user=params.dolphin_user)
time.sleep(5)
def status(self, env):
import status_params
env.set_params(status_params)
check_process_status(status_params.dolphin_run_dir + "alert-server.pid")
if __name__ == "__main__":
DolphinAlertService().execute()

70
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_api_service.py

@ -1,70 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import time
from resource_management import *
from dolphin_env import dolphin_env
class DolphinApiService(Script):
def install(self, env):
import params
env.set_params(params)
self.install_packages(env)
Execute(('chmod', '-R', '777', params.dolphin_home), user=params.dolphin_user, sudo=True)
def configure(self, env):
import params
params.pika_slave = True
env.set_params(params)
dolphin_env()
def start(self, env):
import params
env.set_params(params)
self.configure(env)
#init
init_cmd=format("sh " + params.dolphin_home + "/script/create-dolphinscheduler.sh")
Execute(init_cmd, user=params.dolphin_user)
#upgrade
upgrade_cmd=format("sh " + params.dolphin_home + "/script/upgrade-dolphinscheduler.sh")
Execute(upgrade_cmd, user=params.dolphin_user)
no_op_test = format("ls {dolphin_pidfile_dir}/api-server.pid >/dev/null 2>&1 && ps `cat {dolphin_pidfile_dir}/api-server.pid` | grep `cat {dolphin_pidfile_dir}/api-server.pid` >/dev/null 2>&1")
start_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh start api-server")
Execute(start_cmd, user=params.dolphin_user, not_if=no_op_test)
def stop(self, env):
import params
env.set_params(params)
stop_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh stop api-server")
Execute(stop_cmd, user=params.dolphin_user)
time.sleep(5)
def status(self, env):
import status_params
env.set_params(status_params)
check_process_status(status_params.dolphin_run_dir + "api-server.pid")
if __name__ == "__main__":
DolphinApiService().execute()

123
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_env.py

@ -1,123 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from resource_management import *
def dolphin_env():
import params
Directory(params.dolphin_pidfile_dir,
mode=0777,
owner=params.dolphin_user,
group=params.dolphin_group,
create_parents=True
)
Directory(params.dolphin_log_dir,
mode=0777,
owner=params.dolphin_user,
group=params.dolphin_group,
create_parents=True
)
Directory(params.dolphin_conf_dir,
mode=0777,
owner=params.dolphin_user,
group=params.dolphin_group,
create_parents=True
)
Directory(params.dolphin_common_map['data.basedir.path'],
mode=0777,
owner=params.dolphin_user,
group=params.dolphin_group,
create_parents=True
)
File(format(params.dolphin_env_path),
mode=0777,
content=InlineTemplate(params.dolphin_env_content),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh"),
mode=0755,
content=Template("dolphin-daemon.sh.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_conf_dir + "/master.properties"),
mode=0755,
content=Template("master.properties.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_conf_dir + "/worker.properties"),
mode=0755,
content=Template("worker.properties.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_conf_dir + "/alert.properties"),
mode=0755,
content=Template("alert.properties.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_conf_dir + "/datasource.properties"),
mode=0755,
content=Template("datasource.properties.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_conf_dir + "/application-api.properties"),
mode=0755,
content=Template("application-api.properties.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_conf_dir + "/common.properties"),
mode=0755,
content=Template("common.properties.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_conf_dir + "/quartz.properties"),
mode=0755,
content=Template("quartz.properties.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_conf_dir + "/zookeeper.properties"),
mode=0755,
content=Template("zookeeper.properties.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)

61
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_logger_service.py

@ -1,61 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import time
from resource_management import *
from dolphin_env import dolphin_env
class DolphinLoggerService(Script):
def install(self, env):
import params
env.set_params(params)
self.install_packages(env)
Execute(('chmod', '-R', '777', params.dolphin_home), user=params.dolphin_user, sudo=True)
def configure(self, env):
import params
params.pika_slave = True
env.set_params(params)
dolphin_env()
def start(self, env):
import params
env.set_params(params)
self.configure(env)
no_op_test = format("ls {dolphin_pidfile_dir}/logger-server.pid >/dev/null 2>&1 && ps `cat {dolphin_pidfile_dir}/logger-server.pid` | grep `cat {dolphin_pidfile_dir}/logger-server.pid` >/dev/null 2>&1")
start_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh start logger-server")
Execute(start_cmd, user=params.dolphin_user, not_if=no_op_test)
def stop(self, env):
import params
env.set_params(params)
stop_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh stop logger-server")
Execute(stop_cmd, user=params.dolphin_user)
time.sleep(5)
def status(self, env):
import status_params
env.set_params(status_params)
check_process_status(status_params.dolphin_run_dir + "logger-server.pid")
if __name__ == "__main__":
DolphinLoggerService().execute()

61
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_master_service.py

@ -1,61 +0,0 @@
# -*- coding: utf-8 -*-
"""
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.
"""
import time
from resource_management import *
from dolphin_env import dolphin_env
class DolphinMasterService(Script):
def install(self, env):
import params
env.set_params(params)
self.install_packages(env)
Execute(('chmod', '-R', '777', params.dolphin_home), user=params.dolphin_user, sudo=True)
def configure(self, env):
import params
params.pika_slave = True
env.set_params(params)
dolphin_env()
def start(self, env):
import params
env.set_params(params)
self.configure(env)
no_op_test = format("ls {dolphin_pidfile_dir}/master-server.pid >/dev/null 2>&1 && ps `cat {dolphin_pidfile_dir}/master-server.pid` | grep `cat {dolphin_pidfile_dir}/master-server.pid` >/dev/null 2>&1")
start_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh start master-server")
Execute(start_cmd, user=params.dolphin_user, not_if=no_op_test)
def stop(self, env):
import params
env.set_params(params)
stop_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh stop master-server")
Execute(stop_cmd, user=params.dolphin_user)
time.sleep(5)
def status(self, env):
import status_params
env.set_params(status_params)
check_process_status(status_params.dolphin_run_dir + "master-server.pid")
if __name__ == "__main__":
DolphinMasterService().execute()

60
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/dolphin_worker_service.py

@ -1,60 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import time
from resource_management import *
from dolphin_env import dolphin_env
class DolphinWorkerService(Script):
def install(self, env):
import params
env.set_params(params)
self.install_packages(env)
Execute(('chmod', '-R', '777', params.dolphin_home), user=params.dolphin_user, sudo=True)
def configure(self, env):
import params
params.pika_slave = True
env.set_params(params)
dolphin_env()
def start(self, env):
import params
env.set_params(params)
self.configure(env)
no_op_test = format("ls {dolphin_pidfile_dir}/worker-server.pid >/dev/null 2>&1 && ps `cat {dolphin_pidfile_dir}/worker-server.pid` | grep `cat {dolphin_pidfile_dir}/worker-server.pid` >/dev/null 2>&1")
start_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh start worker-server")
Execute(start_cmd, user=params.dolphin_user, not_if=no_op_test)
def stop(self, env):
import params
env.set_params(params)
stop_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh stop worker-server")
Execute(stop_cmd, user=params.dolphin_user)
time.sleep(5)
def status(self, env):
import status_params
env.set_params(status_params)
check_process_status(status_params.dolphin_run_dir + "worker-server.pid")
if __name__ == "__main__":
DolphinWorkerService().execute()

154
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/params.py

@ -1,154 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import sys
from resource_management import *
from resource_management.core.logger import Logger
from resource_management.libraries.functions import default
Logger.initialize_logger()
reload(sys)
sys.setdefaultencoding('utf-8')
# server configurations
config = Script.get_config()
# conf_dir = "/etc/"
dolphin_home = "/opt/soft/dolphinscheduler"
dolphin_conf_dir = dolphin_home + "/conf"
dolphin_log_dir = dolphin_home + "/logs"
dolphin_bin_dir = dolphin_home + "/bin"
dolphin_lib_jars = dolphin_home + "/lib/*"
dolphin_pidfile_dir = "/opt/soft/run/dolphinscheduler"
rmHosts = default("/clusterHostInfo/rm_host", [])
# dolphin-env
dolphin_env_map = {}
dolphin_env_map.update(config['configurations']['dolphin-env'])
# which user to install and admin dolphin scheduler
dolphin_user = dolphin_env_map['dolphin.user']
dolphin_group = dolphin_env_map['dolphin.group']
# .dolphinscheduler_env.sh
dolphin_env_path = dolphin_conf_dir + '/env/dolphinscheduler_env.sh'
dolphin_env_content = dolphin_env_map['dolphinscheduler-env-content']
# database config
dolphin_database_config = {}
dolphin_database_config['dolphin_database_type'] = dolphin_env_map['dolphin.database.type']
dolphin_database_config['dolphin_database_username'] = dolphin_env_map['dolphin.database.username']
dolphin_database_config['dolphin_database_password'] = dolphin_env_map['dolphin.database.password']
if 'mysql' == dolphin_database_config['dolphin_database_type']:
dolphin_database_config['dolphin_database_driver'] = 'com.mysql.jdbc.Driver'
dolphin_database_config['driverDelegateClass'] = 'org.quartz.impl.jdbcjobstore.StdJDBCDelegate'
dolphin_database_config['dolphin_database_url'] = 'jdbc:mysql://' + dolphin_env_map['dolphin.database.host'] \
+ ':' + dolphin_env_map['dolphin.database.port'] \
+ '/dolphinscheduler?useUnicode=true&characterEncoding=UTF-8'
else:
dolphin_database_config['dolphin_database_driver'] = 'org.postgresql.Driver'
dolphin_database_config['driverDelegateClass'] = 'org.quartz.impl.jdbcjobstore.PostgreSQLDelegate'
dolphin_database_config['dolphin_database_url'] = 'jdbc:postgresql://' + dolphin_env_map['dolphin.database.host'] \
+ ':' + dolphin_env_map['dolphin.database.port'] \
+ '/dolphinscheduler'
# application-alert.properties
dolphin_alert_map = {}
wechat_push_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=$token'
wechat_token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$corpId&corpsecret=$secret'
wechat_team_send_msg = '{\"toparty\":\"$toParty\",\"agentid\":\"$agentId\",\"msgtype\":\"text\",\"text\":{\"content\":\"$msg\"},\"safe\":\"0\"}'
wechat_user_send_msg = '{\"touser\":\"$toUser\",\"agentid\":\"$agentId\",\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"$msg\"}}'
dolphin_alert_config_map = config['configurations']['dolphin-alert']
if dolphin_alert_config_map['enterprise.wechat.enable']:
dolphin_alert_map['enterprise.wechat.push.ur'] = wechat_push_url
dolphin_alert_map['enterprise.wechat.token.url'] = wechat_token_url
dolphin_alert_map['enterprise.wechat.team.send.msg'] = wechat_team_send_msg
dolphin_alert_map['enterprise.wechat.user.send.msg'] = wechat_user_send_msg
dolphin_alert_map.update(dolphin_alert_config_map)
# application-api.properties
dolphin_app_api_map = {}
dolphin_app_api_map.update(config['configurations']['dolphin-application-api'])
# common.properties
dolphin_common_map = {}
if 'yarn-site' in config['configurations'] and \
'yarn.resourcemanager.webapp.address' in config['configurations']['yarn-site']:
yarn_resourcemanager_webapp_address = config['configurations']['yarn-site']['yarn.resourcemanager.webapp.address']
yarn_application_status_address = 'http://' + yarn_resourcemanager_webapp_address + '/ws/v1/cluster/apps/%s'
dolphin_common_map['yarn.application.status.address'] = yarn_application_status_address
rmHosts = default("/clusterHostInfo/rm_host", [])
if len(rmHosts) > 1:
dolphin_common_map['yarn.resourcemanager.ha.rm.ids'] = ','.join(rmHosts)
else:
dolphin_common_map['yarn.resourcemanager.ha.rm.ids'] = ''
dolphin_common_map_tmp = config['configurations']['dolphin-common']
data_basedir_path = dolphin_common_map_tmp['data.basedir.path']
process_exec_basepath = data_basedir_path + '/exec'
data_download_basedir_path = data_basedir_path + '/download'
dolphin_common_map['process.exec.basepath'] = process_exec_basepath
dolphin_common_map['data.download.basedir.path'] = data_download_basedir_path
dolphin_common_map['dolphinscheduler.env.path'] = dolphin_env_path
dolphin_common_map.update(config['configurations']['dolphin-common'])
# datasource.properties
dolphin_datasource_map = {}
dolphin_datasource_map['spring.datasource.type'] = 'com.alibaba.druid.pool.DruidDataSource'
dolphin_datasource_map['spring.datasource.driver-class-name'] = dolphin_database_config['dolphin_database_driver']
dolphin_datasource_map['spring.datasource.url'] = dolphin_database_config['dolphin_database_url']
dolphin_datasource_map['spring.datasource.username'] = dolphin_database_config['dolphin_database_username']
dolphin_datasource_map['spring.datasource.password'] = dolphin_database_config['dolphin_database_password']
dolphin_datasource_map.update(config['configurations']['dolphin-datasource'])
# master.properties
dolphin_master_map = config['configurations']['dolphin-master']
# quartz.properties
dolphin_quartz_map = {}
dolphin_quartz_map['org.quartz.jobStore.driverDelegateClass'] = dolphin_database_config['driverDelegateClass']
dolphin_quartz_map.update(config['configurations']['dolphin-quartz'])
# worker.properties
dolphin_worker_map = config['configurations']['dolphin-worker']
# zookeeper.properties
dolphin_zookeeper_map={}
zookeeperHosts = default("/clusterHostInfo/zookeeper_hosts", [])
if len(zookeeperHosts) > 0 and "clientPort" in config['configurations']['zoo.cfg']:
clientPort = config['configurations']['zoo.cfg']['clientPort']
zookeeperPort = ":" + clientPort + ","
dolphin_zookeeper_map['zookeeper.quorum'] = zookeeperPort.join(zookeeperHosts) + ":" + clientPort
dolphin_zookeeper_map.update(config['configurations']['dolphin-zookeeper'])

31
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/service_check.py

@ -1,31 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from resource_management import *
from resource_management.libraries.functions import get_unique_id_and_date
class ServiceCheck(Script):
def service_check(self, env):
import params
#env.set_params(params)
# Execute(format("which pika_server"))
if __name__ == "__main__":
ServiceCheck().execute()

23
ambari_plugin/common-services/DOLPHIN/2.0.0/package/scripts/status_params.py

@ -1,23 +0,0 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from resource_management import *
config = Script.get_config()
dolphin_run_dir = "/opt/soft/run/dolphinscheduler/"

20
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/application-api.properties.j2

@ -1,20 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
{% for key, value in dolphin_app_api_map.iteritems() -%}
{{key}}={{value}}
{% endfor %}

20
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/common.properties.j2

@ -1,20 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
{% for key, value in dolphin_common_map.iteritems() -%}
{{key}}={{value}}
{% endfor %}

20
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/datasource.properties.j2

@ -1,20 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
{% for key, value in dolphin_datasource_map.iteritems() -%}
{{key}}={{value}}
{% endfor %}

116
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/dolphin-daemon.sh.j2

@ -1,116 +0,0 @@
#!/bin/sh
#
# 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.
#
usage="Usage: dolphinscheduler-daemon.sh (start|stop) <command> "
# if no args specified, show usage
if [ $# -le 1 ]; then
echo $usage
exit 1
fi
startStop=$1
shift
command=$1
shift
echo "Begin $startStop $command......"
BIN_DIR=`dirname $0`
BIN_DIR=`cd "$BIN_DIR"; pwd`
DOLPHINSCHEDULER_HOME=$BIN_DIR/..
export HOSTNAME=`hostname`
DOLPHINSCHEDULER_LIB_JARS={{dolphin_lib_jars}}
DOLPHINSCHEDULER_OPTS="-server -Xmx16g -Xms4g -Xss512k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70"
STOP_TIMEOUT=5
log={{dolphin_log_dir}}/dolphinscheduler-$command-$HOSTNAME.out
pid={{dolphin_pidfile_dir}}/$command.pid
cd $DOLPHINSCHEDULER_HOME
if [ "$command" = "api-server" ]; then
LOG_FILE="-Dlogging.config={{dolphin_conf_dir}}/logback-api.xml -Dspring.profiles.active=api"
CLASS=org.apache.dolphinscheduler.api.ApiApplicationServer
elif [ "$command" = "master-server" ]; then
LOG_FILE="-Dlogging.config={{dolphin_conf_dir}}/logback-master.xml -Ddruid.mysql.usePingMethod=false"
CLASS=org.apache.dolphinscheduler.server.master.MasterServer
elif [ "$command" = "worker-server" ]; then
LOG_FILE="-Dlogging.config={{dolphin_conf_dir}}/logback-worker.xml -Ddruid.mysql.usePingMethod=false"
CLASS=org.apache.dolphinscheduler.server.worker.WorkerServer
elif [ "$command" = "alert-server" ]; then
LOG_FILE="-Dlogging.config={{dolphin_conf_dir}}/logback-alert.xml"
CLASS=org.apache.dolphinscheduler.alert.AlertServer
elif [ "$command" = "logger-server" ]; then
CLASS=org.apache.dolphinscheduler.server.log.LoggerServer
else
echo "Error: No command named \`$command' was found."
exit 1
fi
case $startStop in
(start)
if [ -f $pid ]; then
if kill -0 `cat $pid` > /dev/null 2>&1; then
echo $command running as process `cat $pid`. Stop it first.
exit 1
fi
fi
echo starting $command, logging to $log
exec_command="$LOG_FILE $DOLPHINSCHEDULER_OPTS -classpath {{dolphin_conf_dir}}:{{dolphin_lib_jars}} $CLASS"
echo "nohup java $exec_command > $log 2>&1 < /dev/null &"
nohup java $exec_command > $log 2>&1 < /dev/null &
echo $! > $pid
;;
(stop)
if [ -f $pid ]; then
TARGET_PID=`cat $pid`
if kill -0 $TARGET_PID > /dev/null 2>&1; then
echo stopping $command
kill $TARGET_PID
sleep $STOP_TIMEOUT
if kill -0 $TARGET_PID > /dev/null 2>&1; then
echo "$command did not stop gracefully after $STOP_TIMEOUT seconds: killing with kill -9"
kill -9 $TARGET_PID
fi
else
echo no $command to stop
fi
rm -f $pid
else
echo no $command to stop
fi
;;
(*)
echo $usage
exit 1
;;
esac
echo "End $startStop $command."

20
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/master.properties.j2

@ -1,20 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
{% for key, value in dolphin_master_map.iteritems() -%}
{{key}}={{value}}
{% endfor %}

20
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/quartz.properties.j2

@ -1,20 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
{% for key, value in dolphin_quartz_map.iteritems() -%}
{{key}}={{value}}
{% endfor %}

20
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/worker.properties.j2

@ -1,20 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
{% for key, value in dolphin_worker_map.iteritems() -%}
{{key}}={{value}}
{% endfor %}

20
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/zookeeper.properties.j2

@ -1,20 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
{% for key, value in dolphin_zookeeper_map.iteritems() -%}
{{key}}={{value}}
{% endfor %}

26
ambari_plugin/common-services/DOLPHIN/2.0.0/quicklinks/quicklinks.json

@ -1,26 +0,0 @@
{
"name": "default",
"description": "default quick links configuration",
"configuration": {
"protocol":
{
"type":"http"
},
"links": [
{
"name": "dolphin-application-ui",
"label": "DolphinApplication UI",
"requires_user_name": "false",
"component_name": "DOLPHIN_API",
"url": "%@://%@:%@/dolphinscheduler/ui/view/login/index.html",
"port":{
"http_property": "server.port",
"http_default_port": "12345",
"regex": "^(\\d+)$",
"site": "dolphin-application-api"
}
}
]
}
}

661
ambari_plugin/common-services/DOLPHIN/2.0.0/themes/theme.json

@ -1,661 +0,0 @@
{
"name": "default",
"description": "Default theme for Dolphin Scheduler service",
"configuration": {
"layouts": [
{
"name": "default",
"tabs": [
{
"name": "settings",
"display-name": "Settings",
"layout": {
"tab-rows": "3",
"tab-columns": "3",
"sections": [
{
"name": "dolphin-env-config",
"display-name": "Dolphin Env Config",
"row-index": "0",
"column-index": "0",
"row-span": "1",
"column-span": "2",
"section-rows": "1",
"section-columns": "2",
"subsections": [
{
"name": "env-row1-col1",
"display-name": "Deploy User Info",
"row-index": "0",
"column-index": "0",
"row-span": "1",
"column-span": "1"
},
{
"name": "env-row1-col2",
"display-name": "System Env Optimization",
"row-index": "0",
"column-index": "1",
"row-span": "1",
"column-span": "1"
}
]
},
{
"name": "dolphin-database-config",
"display-name": "Database Config",
"row-index": "1",
"column-index": "0",
"row-span": "1",
"column-span": "2",
"section-rows": "1",
"section-columns": "3",
"subsections": [
{
"name": "database-row1-col1",
"row-index": "0",
"column-index": "0",
"row-span": "1",
"column-span": "1"
},
{
"name": "database-row1-col2",
"row-index": "0",
"column-index": "1",
"row-span": "1",
"column-span": "1"
},
{
"name": "database-row1-col3",
"row-index": "0",
"column-index": "2",
"row-span": "1",
"column-span": "1"
}
]
},
{
"name": "dynamic-config",
"row-index": "2",
"column-index": "0",
"row-span": "1",
"column-span": "2",
"section-rows": "1",
"section-columns": "3",
"subsections": [
{
"name": "dynamic-row1-col1",
"display-name": "Resource FS Config",
"row-index": "0",
"column-index": "0",
"row-span": "1",
"column-span": "1"
},
{
"name": "dynamic-row1-col2",
"display-name": "Kerberos Info",
"row-index": "0",
"column-index": "1",
"row-span": "1",
"column-span": "1"
},
{
"name": "dynamic-row1-col3",
"display-name": "Wechat Info",
"row-index": "0",
"column-index": "1",
"row-span": "1",
"column-span": "1"
}
]
}
]
}
}
]
}
],
"placement": {
"configuration-layout": "default",
"configs": [
{
"config": "dolphin-env/dolphin.database.type",
"subsection-name": "database-row1-col1"
},
{
"config": "dolphin-env/dolphin.database.host",
"subsection-name": "database-row1-col2"
},
{
"config": "dolphin-env/dolphin.database.port",
"subsection-name": "database-row1-col2"
},
{
"config": "dolphin-env/dolphin.database.username",
"subsection-name": "database-row1-col3"
},
{
"config": "dolphin-env/dolphin.database.password",
"subsection-name": "database-row1-col3"
},
{
"config": "dolphin-env/dolphin.user",
"subsection-name": "env-row1-col1"
},
{
"config": "dolphin-env/dolphin.group",
"subsection-name": "env-row1-col1"
},
{
"config": "dolphin-env/dolphinscheduler-env-content",
"subsection-name": "env-row1-col2"
},
{
"config": "dolphin-common/resource.storage.type",
"subsection-name": "dynamic-row1-col1"
},
{
"config": "dolphin-common/resource.upload.path",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"dolphin-common/resource.storage.type"
],
"if": "${dolphin-common/resource.storage.type} === HDFS || ${dolphin-common/resource.storage.type} === S3",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/hdfs.root.user",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"dolphin-common/resource.storage.type"
],
"if": "${dolphin-common/resource.storage.type} === HDFS",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/data.store2hdfs.basepath",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"dolphin-common/resource.storage.type"
],
"if": "${dolphin-common/resource.storage.type} === HDFS",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/fs.defaultFS",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"dolphin-common/resource.storage.type"
],
"if": "${dolphin-common/resource.storage.type} === HDFS",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/fs.s3a.endpoint",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"dolphin-common/resource.storage.type"
],
"if": "${dolphin-common/resource.storage.type} === S3",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/fs.s3a.access.key",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"dolphin-common/resource.storage.type"
],
"if": "${dolphin-common/resource.storage.type} === S3",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/fs.s3a.secret.key",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"dolphin-common/resource.storage.type"
],
"if": "${dolphin-common/resource.storage.type} === S3",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/hadoop.security.authentication.startup.state",
"subsection-name": "dynamic-row1-col2"
},
{
"config": "dolphin-common/java.security.krb5.conf.path",
"subsection-name": "dynamic-row1-col2",
"depends-on": [
{
"configs":[
"dolphin-common/hadoop.security.authentication.startup.state"
],
"if": "${dolphin-common/hadoop.security.authentication.startup.state}",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/login.user.keytab.username",
"subsection-name": "dynamic-row1-col2",
"depends-on": [
{
"configs":[
"dolphin-common/hadoop.security.authentication.startup.state"
],
"if": "${dolphin-common/hadoop.security.authentication.startup.state}",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/login.user.keytab.path",
"subsection-name": "dynamic-row1-col2",
"depends-on": [
{
"configs":[
"dolphin-common/hadoop.security.authentication.startup.state"
],
"if": "${dolphin-common/hadoop.security.authentication.startup.state}",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-common/kerberos.expire.time",
"subsection-name": "dynamic-row1-col2",
"depends-on": [
{
"configs":[
"dolphin-common/hadoop.security.authentication.startup.state"
],
"if": "${dolphin-common/hadoop.security.authentication.startup.state}",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-alert/enterprise.wechat.enable",
"subsection-name": "dynamic-row1-col3"
},
{
"config": "dolphin-alert/enterprise.wechat.corp.id",
"subsection-name": "dynamic-row1-col3",
"depends-on": [
{
"configs":[
"dolphin-alert/enterprise.wechat.enable"
],
"if": "${dolphin-alert/enterprise.wechat.enable}",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-alert/enterprise.wechat.secret",
"subsection-name": "dynamic-row1-col3",
"depends-on": [
{
"configs":[
"dolphin-alert/enterprise.wechat.enable"
],
"if": "${dolphin-alert/enterprise.wechat.enable}",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-alert/enterprise.wechat.agent.id",
"subsection-name": "dynamic-row1-col3",
"depends-on": [
{
"configs":[
"dolphin-alert/enterprise.wechat.enable"
],
"if": "${dolphin-alert/enterprise.wechat.enable}",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "dolphin-alert/enterprise.wechat.users",
"subsection-name": "dynamic-row1-col3",
"depends-on": [
{
"configs":[
"dolphin-alert/enterprise.wechat.enable"
],
"if": "${dolphin-alert/enterprise.wechat.enable}",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
}
]
},
"widgets": [
{
"config": "dolphin-env/dolphin.database.type",
"widget": {
"type": "combo"
}
},
{
"config": "dolphin-env/dolphin.database.host",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-env/dolphin.database.port",
"widget": {
"type": "text-field",
"units": [
{
"unit-name": "int"
}
]
}
},
{
"config": "dolphin-env/dolphin.database.username",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-env/dolphin.database.password",
"widget": {
"type": "password"
}
},
{
"config": "dolphin-env/dolphin.user",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-env/dolphin.group",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-env/dolphinscheduler-env-content",
"widget": {
"type": "text-area"
}
},
{
"config": "dolphin-common/resource.storage.type",
"widget": {
"type": "combo"
}
},
{
"config": "dolphin-common/resource.upload.path",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/hdfs.root.user",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/data.store2hdfs.basepath",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/fs.defaultFS",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/fs.s3a.endpoint",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/fs.s3a.access.key",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/fs.s3a.secret.key",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/hadoop.security.authentication.startup.state",
"widget": {
"type": "toggle"
}
},
{
"config": "dolphin-common/java.security.krb5.conf.path",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/login.user.keytab.username",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/login.user.keytab.path",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-common/kerberos.expire.time",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-alert/enterprise.wechat.enable",
"widget": {
"type": "toggle"
}
},
{
"config": "dolphin-alert/enterprise.wechat.corp.id",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-alert/enterprise.wechat.secret",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-alert/enterprise.wechat.agent.id",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-alert/enterprise.wechat.users",
"widget": {
"type": "text-field"
}
}
]
}
}

1
docker/docker-compose.yml

@ -23,6 +23,7 @@ services:
- "2181:2181" - "2181:2181"
environment: environment:
ZOO_MY_ID: 1 ZOO_MY_ID: 1
ZOO_4LW_COMMANDS_WHITELIST: srvr,ruok,wchs,cons
db: db:
image: postgres image: postgres
container_name: postgres container_name: postgres

30
dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java

@ -16,8 +16,11 @@
*/ */
package org.apache.dolphinscheduler.alert; package org.apache.dolphinscheduler.alert;
import org.apache.dolphinscheduler.alert.plugin.EmailAlertPlugin;
import org.apache.dolphinscheduler.alert.runner.AlertSender; import org.apache.dolphinscheduler.alert.runner.AlertSender;
import org.apache.dolphinscheduler.alert.utils.Constants; import org.apache.dolphinscheduler.alert.utils.Constants;
import org.apache.dolphinscheduler.alert.utils.PropertyUtils;
import org.apache.dolphinscheduler.common.plugin.FilePluginManager;
import org.apache.dolphinscheduler.common.thread.Stopper; import org.apache.dolphinscheduler.common.thread.Stopper;
import org.apache.dolphinscheduler.dao.AlertDao; import org.apache.dolphinscheduler.dao.AlertDao;
import org.apache.dolphinscheduler.dao.DaoFactory; import org.apache.dolphinscheduler.dao.DaoFactory;
@ -41,34 +44,47 @@ public class AlertServer {
private static AlertServer instance; private static AlertServer instance;
public AlertServer() { private FilePluginManager alertPluginManager;
private static final String[] whitePrefixes = new String[]{"org.apache.dolphinscheduler.plugin.utils."};
private static final String[] excludePrefixes = new String[]{
"org.apache.dolphinscheduler.plugin.",
"ch.qos.logback.",
"org.slf4j."
};
public AlertServer() {
alertPluginManager =
new FilePluginManager(PropertyUtils.getString(Constants.PLUGIN_DIR), whitePrefixes, excludePrefixes);
// add default alert plugins
alertPluginManager.addPlugin(new EmailAlertPlugin());
} }
public synchronized static AlertServer getInstance(){ public synchronized static AlertServer getInstance() {
if (null == instance) { if (null == instance) {
instance = new AlertServer(); instance = new AlertServer();
} }
return instance; return instance;
} }
public void start(){ public void start() {
logger.info("alert server ready start "); logger.info("alert server ready start ");
while (Stopper.isRunning()){ while (Stopper.isRunning()) {
try { try {
Thread.sleep(Constants.ALERT_SCAN_INTERVAL); Thread.sleep(Constants.ALERT_SCAN_INTERVAL);
} catch (InterruptedException e) { } catch (InterruptedException e) {
logger.error(e.getMessage(),e); logger.error(e.getMessage(), e);
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
List<Alert> alerts = alertDao.listWaitExecutionAlert(); List<Alert> alerts = alertDao.listWaitExecutionAlert();
alertSender = new AlertSender(alerts, alertDao); alertSender = new AlertSender(alerts, alertDao, alertPluginManager);
alertSender.run(); alertSender.run();
} }
} }
public static void main(String[] args){ public static void main(String[] args) {
AlertServer alertServer = AlertServer.getInstance(); AlertServer alertServer = AlertServer.getInstance();
alertServer.start(); alertServer.start();
} }

5
dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java

@ -17,7 +17,6 @@
package org.apache.dolphinscheduler.alert.manager; package org.apache.dolphinscheduler.alert.manager;
import org.apache.dolphinscheduler.alert.utils.MailUtils; import org.apache.dolphinscheduler.alert.utils.MailUtils;
import org.apache.dolphinscheduler.common.enums.ShowType;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -35,7 +34,7 @@ public class EmailManager {
* @param showType the showType * @param showType the showType
* @return the send result * @return the send result
*/ */
public Map<String,Object> send(List<String> receviersList,List<String> receviersCcList,String title,String content,ShowType showType){ public Map<String,Object> send(List<String> receviersList,List<String> receviersCcList,String title,String content,String showType){
return MailUtils.sendMails(receviersList, receviersCcList, title, content, showType); return MailUtils.sendMails(receviersList, receviersCcList, title, content, showType);
} }
@ -48,7 +47,7 @@ public class EmailManager {
* @param showType the showType * @param showType the showType
* @return the send result * @return the send result
*/ */
public Map<String,Object> send(List<String> receviersList,String title,String content,ShowType showType){ public Map<String,Object> send(List<String> receviersList,String title,String content,String showType){
return MailUtils.sendMails(receviersList,title, content, showType); return MailUtils.sendMails(receviersList,title, content, showType);
} }

10
dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java

@ -18,7 +18,7 @@ package org.apache.dolphinscheduler.alert.manager;
import org.apache.dolphinscheduler.alert.utils.Constants; import org.apache.dolphinscheduler.alert.utils.Constants;
import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils; import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils;
import org.apache.dolphinscheduler.dao.entity.Alert; import org.apache.dolphinscheduler.plugin.model.AlertInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -35,18 +35,18 @@ public class EnterpriseWeChatManager {
private static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatManager.class); private static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatManager.class);
/** /**
* Enterprise We Chat send * Enterprise We Chat send
* @param alert the alert * @param alertInfo the alert info
* @param token the token * @param token the token
* @return the send result * @return the send result
*/ */
public Map<String,Object> send(Alert alert, String token){ public Map<String,Object> send(AlertInfo alertInfo, String token){
Map<String,Object> retMap = new HashMap<>(); Map<String,Object> retMap = new HashMap<>();
retMap.put(Constants.STATUS, false); retMap.put(Constants.STATUS, false);
String agentId = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_AGENT_ID; String agentId = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_AGENT_ID;
String users = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_USERS; String users = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_USERS;
List<String> userList = Arrays.asList(users.split(",")); List<String> userList = Arrays.asList(users.split(","));
logger.info("send message {}",alert); logger.info("send message {}", alertInfo.getAlertData().getTitle());
String msg = EnterpriseWeChatUtils.makeUserSendMsg(userList, agentId,EnterpriseWeChatUtils.markdownByAlert(alert)); String msg = EnterpriseWeChatUtils.makeUserSendMsg(userList, agentId,EnterpriseWeChatUtils.markdownByAlert(alertInfo.getAlertData()));
try { try {
EnterpriseWeChatUtils.sendEnterpriseWeChat(Constants.UTF_8, msg, token); EnterpriseWeChatUtils.sendEnterpriseWeChat(Constants.UTF_8, msg, token);
} catch (IOException e) { } catch (IOException e) {

133
dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPlugin.java

@ -0,0 +1,133 @@
/*
* 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.plugin;
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.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.plugin.api.AlertPlugin;
import org.apache.dolphinscheduler.plugin.model.AlertData;
import org.apache.dolphinscheduler.plugin.model.AlertInfo;
import org.apache.dolphinscheduler.plugin.model.PluginName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* EmailAlertPlugin
*
* This plugin is a default plugin, and mix up email and enterprise wechat, because adapt with former alert behavior
*/
public class EmailAlertPlugin implements AlertPlugin {
private static final Logger logger = LoggerFactory.getLogger(EmailAlertPlugin.class);
private PluginName pluginName;
private static final EmailManager emailManager = new EmailManager();
private static final EnterpriseWeChatManager weChatManager = new EnterpriseWeChatManager();
public EmailAlertPlugin() {
this.pluginName = new PluginName();
this.pluginName.setEnglish(Constants.PLUGIN_DEFAULT_EMAIL_EN);
this.pluginName.setChinese(Constants.PLUGIN_DEFAULT_EMAIL_CH);
}
@Override
public String getId() {
return Constants.PLUGIN_DEFAULT_EMAIL;
}
@Override
public PluginName getName() {
return pluginName;
}
@Override
@SuppressWarnings("unchecked")
public Map<String, Object> process(AlertInfo info) {
Map<String, Object> retMaps = new HashMap<>();
AlertData alert = info.getAlertData();
List<String> receviersList = (List<String>) info.getProp(Constants.PLUGIN_DEFAULT_EMAIL_RECEIVERS);
// receiving group list
// custom receiver
String receivers = alert.getReceivers();
if (StringUtils.isNotEmpty(receivers)) {
String[] splits = receivers.split(",");
receviersList.addAll(Arrays.asList(splits));
}
List<String> receviersCcList = new ArrayList<>();
// Custom Copier
String receiversCc = alert.getReceiversCc();
if (StringUtils.isNotEmpty(receiversCc)) {
String[] splits = receiversCc.split(",");
receviersCcList.addAll(Arrays.asList(splits));
}
if (CollectionUtils.isEmpty(receviersList) && CollectionUtils.isEmpty(receviersCcList)) {
logger.warn("alert send error : At least one receiver address required");
retMaps.put(Constants.STATUS, "false");
retMaps.put(Constants.MESSAGE, "execution failure,At least one receiver address required.");
return retMaps;
}
retMaps = emailManager.send(receviersList, receviersCcList, alert.getTitle(), alert.getContent(),
alert.getShowType());
//send flag
boolean flag = false;
if (retMaps == null) {
retMaps = new HashMap<>();
retMaps.put(Constants.MESSAGE, "alert send error.");
retMaps.put(Constants.STATUS, "false");
logger.info("alert send error : {}", retMaps.get(Constants.MESSAGE));
return retMaps;
}
flag = Boolean.parseBoolean(String.valueOf(retMaps.get(Constants.STATUS)));
if (flag) {
logger.info("alert send success");
retMaps.put(Constants.MESSAGE, "email send success.");
if (EnterpriseWeChatUtils.isEnable()) {
logger.info("Enterprise WeChat is enable!");
try {
String token = EnterpriseWeChatUtils.getToken();
weChatManager.send(info, token);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
} else {
retMaps.put(Constants.MESSAGE, "alert send error.");
logger.info("alert send error : {}", retMaps.get(Constants.MESSAGE));
}
return retMaps;
}
}

130
dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java

@ -16,139 +16,85 @@
*/ */
package org.apache.dolphinscheduler.alert.runner; 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.Constants;
import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils;
import org.apache.dolphinscheduler.common.enums.AlertStatus; import org.apache.dolphinscheduler.common.enums.AlertStatus;
import org.apache.dolphinscheduler.common.enums.AlertType; import org.apache.dolphinscheduler.common.plugin.PluginManager;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.dao.AlertDao; import org.apache.dolphinscheduler.dao.AlertDao;
import org.apache.dolphinscheduler.dao.entity.Alert; import org.apache.dolphinscheduler.dao.entity.Alert;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.plugin.api.AlertPlugin;
import org.apache.dolphinscheduler.plugin.model.AlertData;
import org.apache.dolphinscheduler.plugin.model.AlertInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* alert sender * alert sender
*/ */
public class AlertSender{ public class AlertSender {
private static final Logger logger = LoggerFactory.getLogger(AlertSender.class); 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 List<Alert> alertList;
private AlertDao alertDao; private AlertDao alertDao;
private PluginManager pluginManager;
public AlertSender() {
}
public AlertSender(){} public AlertSender(List<Alert> alertList, AlertDao alertDao, PluginManager pluginManager) {
public AlertSender(List<Alert> alertList, AlertDao alertDao){
super(); super();
this.alertList = alertList; this.alertList = alertList;
this.alertDao = alertDao; this.alertDao = alertDao;
this.pluginManager = pluginManager;
} }
public void run() { public void run() {
List<User> users; List<User> users;
Map<String, Object> retMaps = null; Map<String, Object> retMaps = null;
for(Alert alert:alertList){ for (Alert alert : alertList) {
users = alertDao.listUserByAlertgroupId(alert.getAlertGroupId()); users = alertDao.listUserByAlertgroupId(alert.getAlertGroupId());
// receiving group list // receiving group list
List<String> receviersList = new ArrayList<>(); List<String> receviersList = new ArrayList<>();
for(User user:users){ for (User user : users) {
receviersList.add(user.getEmail()); receviersList.add(user.getEmail());
} }
// custom receiver
String receivers = alert.getReceivers();
if (StringUtils.isNotEmpty(receivers)){
String[] splits = receivers.split(",");
receviersList.addAll(Arrays.asList(splits));
}
// copy list AlertData alertData = new AlertData();
List<String> receviersCcList = new ArrayList<>(); alertData.setId(alert.getId())
.setAlertGroupId(alert.getAlertGroupId())
.setContent(alert.getContent())
// Custom Copier .setLog(alert.getLog())
String receiversCc = alert.getReceiversCc(); .setReceivers(alert.getReceivers())
.setReceiversCc(alert.getReceiversCc())
if (StringUtils.isNotEmpty(receiversCc)){ .setShowType(alert.getShowType().getDescp())
String[] splits = receiversCc.split(","); .setTitle(alert.getTitle());
receviersCcList.addAll(Arrays.asList(splits));
} AlertInfo alertInfo = new AlertInfo();
alertInfo.setAlertData(alertData);
if (CollectionUtils.isEmpty(receviersList) && CollectionUtils.isEmpty(receviersCcList)) {
logger.warn("alert send error : At least one receiver address required"); alertInfo.addProp("receivers", receviersList);
alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE, "execution failure,At least one receiver address required.", alert.getId());
continue; AlertPlugin emailPlugin = pluginManager.findOne(Constants.PLUGIN_DEFAULT_EMAIL);
} retMaps = emailPlugin.process(alertInfo);
if (alert.getAlertType() == AlertType.EMAIL){ if (retMaps == null) {
retMaps = emailManager.send(receviersList,receviersCcList, alert.getTitle(), alert.getContent(),alert.getShowType()); alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE, "alert send error", alert.getId());
logger.info("alert send error : return value is null");
alert.setInfo(retMaps); } else if (!Boolean.parseBoolean(String.valueOf(retMaps.get(Constants.STATUS)))) {
}else if (alert.getAlertType() == AlertType.SMS){ alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE, String.valueOf(retMaps.get(Constants.MESSAGE)), alert.getId());
retMaps = emailManager.send(getReciversForSMS(users), alert.getTitle(), alert.getContent(),alert.getShowType()); logger.info("alert send error : {}", retMaps.get(Constants.MESSAGE));
alert.setInfo(retMaps);
} else { } else {
logger.error("AlertType is not defined. code: {}, descp: {}", alertDao.updateAlert(AlertStatus.EXECUTION_SUCCESS, (String) retMaps.get(Constants.MESSAGE), alert.getId());
alert.getAlertType().getCode(),
alert.getAlertType().getDescp());
return;
}
//send flag
boolean flag = false;
if (null != retMaps) {
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"); logger.info("alert send success");
if (EnterpriseWeChatUtils.isEnable()) {
logger.info("Enterprise WeChat is enable!");
try {
String token = EnterpriseWeChatUtils.getToken();
weChatManager.send(alert, token);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
} else {
if (null != retMaps) {
alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE, String.valueOf(retMaps.get(Constants.MESSAGE)), alert.getId());
logger.info("alert send error : {}", 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;
}
} }

17
dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java

@ -156,4 +156,21 @@ public class Constants {
public static final String ENTERPRISE_WECHAT_AGENT_ID = "enterprise.wechat.agent.id"; public static final String ENTERPRISE_WECHAT_AGENT_ID = "enterprise.wechat.agent.id";
public static final String ENTERPRISE_WECHAT_USERS = "enterprise.wechat.users"; public static final String ENTERPRISE_WECHAT_USERS = "enterprise.wechat.users";
/**
* plugin config
*/
public static final String PLUGIN_DIR = "plugin.dir";
public static final String PLUGIN_DEFAULT_EMAIL = "email";
public static final String PLUGIN_DEFAULT_EMAIL_CH = "邮件";
public static final String PLUGIN_DEFAULT_EMAIL_EN = "email";
public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERS = "receivers";
public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERCCS = "receiverCcs";
public static final String RETMAP_MSG = "msg";
} }

17
dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java

@ -18,10 +18,10 @@ package org.apache.dolphinscheduler.alert.utils;
import org.apache.dolphinscheduler.common.enums.ShowType; import org.apache.dolphinscheduler.common.enums.ShowType;
import org.apache.dolphinscheduler.common.utils.StringUtils; import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.dao.entity.Alert;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.google.common.reflect.TypeToken; import com.google.common.reflect.TypeToken;
import org.apache.dolphinscheduler.plugin.model.AlertData;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
@ -66,15 +66,17 @@ public class EnterpriseWeChatUtils {
* get Enterprise WeChat is enable * get Enterprise WeChat is enable
* @return isEnable * @return isEnable
*/ */
public static Boolean isEnable(){ public static boolean isEnable(){
Boolean isEnable = false; Boolean isEnable = null;
try { try {
isEnable = PropertyUtils.getBoolean(Constants.ENTERPRISE_WECHAT_ENABLE); isEnable = PropertyUtils.getBoolean(Constants.ENTERPRISE_WECHAT_ENABLE);
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(),e); logger.error(e.getMessage(),e);
} }
if (isEnable == null) {
return false;
}
return isEnable; return isEnable;
} }
/** /**
@ -253,14 +255,13 @@ public class EnterpriseWeChatUtils {
/** /**
* Determine the mardown style based on the show type of the alert * Determine the mardown style based on the show type of the alert
* @param alert the alert
* @return the markdown alert table/text * @return the markdown alert table/text
*/ */
public static String markdownByAlert(Alert alert){ public static String markdownByAlert(AlertData alert){
String result = ""; String result = "";
if (alert.getShowType() == ShowType.TABLE) { if (alert.getShowType().equals(ShowType.TABLE.getDescp())) {
result = markdownTable(alert.getTitle(),alert.getContent()); result = markdownTable(alert.getTitle(),alert.getContent());
}else if(alert.getShowType() == ShowType.TEXT){ }else if(alert.getShowType().equals(ShowType.TEXT.getDescp())){
result = markdownText(alert.getTitle(),alert.getContent()); result = markdownText(alert.getTitle(),alert.getContent());
} }
return result; return result;

16
dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java

@ -74,7 +74,7 @@ public class MailUtils {
* @param showType the show type * @param showType the show type
* @return the result map * @return the result map
*/ */
public static Map<String,Object> sendMails(Collection<String> receivers, String title, String content,ShowType showType) { public static Map<String,Object> sendMails(Collection<String> receivers, String title, String content,String showType) {
return sendMails(receivers, null, title, content, showType); return sendMails(receivers, null, title, content, showType);
} }
@ -87,7 +87,7 @@ public class MailUtils {
* @param showType the show type * @param showType the show type
* @return the send result * @return the send result
*/ */
public static Map<String,Object> sendMails(Collection<String> receivers, Collection<String> receiversCc, String title, String content, ShowType showType) { public static Map<String,Object> sendMails(Collection<String> receivers, Collection<String> receiversCc, String title, String content, String showType) {
Map<String,Object> retMap = new HashMap<>(); Map<String,Object> retMap = new HashMap<>();
retMap.put(Constants.STATUS, false); retMap.put(Constants.STATUS, false);
@ -98,7 +98,7 @@ public class MailUtils {
receivers.removeIf(StringUtils::isEmpty); receivers.removeIf(StringUtils::isEmpty);
if (showType == ShowType.TABLE || showType == ShowType.TEXT){ if (showType.equals(ShowType.TABLE.getDescp()) || showType.equals(ShowType.TEXT.getDescp())) {
// send email // send email
HtmlEmail email = new HtmlEmail(); HtmlEmail email = new HtmlEmail();
@ -125,10 +125,10 @@ public class MailUtils {
} catch (Exception e) { } catch (Exception e) {
handleException(receivers, retMap, e); handleException(receivers, retMap, e);
} }
}else if (showType == ShowType.ATTACHMENT || showType == ShowType.TABLEATTACHMENT){ }else if (showType.equals(ShowType.ATTACHMENT.getDescp()) || showType.equals(ShowType.TABLEATTACHMENT.getDescp())) {
try { try {
String partContent = (showType == ShowType.ATTACHMENT ? "Please see the attachment " + title + Constants.EXCEL_SUFFIX_XLS : htmlTable(content,false)); String partContent = (showType.equals(ShowType.ATTACHMENT.getDescp()) ? "Please see the attachment " + title + Constants.EXCEL_SUFFIX_XLS : htmlTable(content,false));
attachment(receivers,receiversCc,title,content,partContent); attachment(receivers,receiversCc,title,content,partContent);
@ -290,7 +290,7 @@ public class MailUtils {
* @return the result map * @return the result map
* @throws EmailException * @throws EmailException
*/ */
private static Map<String, Object> getStringObjectMap(String title, String content, ShowType showType, Map<String, Object> retMap, HtmlEmail email) throws EmailException { private static Map<String, Object> getStringObjectMap(String title, String content, String showType, Map<String, Object> retMap, HtmlEmail email) throws EmailException {
/** /**
* the subject of the message to be sent * the subject of the message to be sent
@ -299,9 +299,9 @@ public class MailUtils {
/** /**
* to send information, you can use HTML tags in mail content because of the use of HtmlEmail * to send information, you can use HTML tags in mail content because of the use of HtmlEmail
*/ */
if (showType == ShowType.TABLE) { if (showType.equals(ShowType.TABLE.getDescp())) {
email.setMsg(htmlTable(content)); email.setMsg(htmlTable(content));
} else if (showType == ShowType.TEXT) { } else if (showType.equals(ShowType.TEXT.getDescp())) {
email.setMsg(htmlText(content)); email.setMsg(htmlText(content));
} }

2
dolphinscheduler-alert/src/main/resources/alert.properties

@ -45,5 +45,5 @@ enterprise.wechat.enable=false
#enterprise.wechat.team.send.msg={\"toparty\":\"$toParty\",\"agentid\":\"$agentId\",\"msgtype\":\"text\",\"text\":{\"content\":\"$msg\"},\"safe\":\"0\"} #enterprise.wechat.team.send.msg={\"toparty\":\"$toParty\",\"agentid\":\"$agentId\",\"msgtype\":\"text\",\"text\":{\"content\":\"$msg\"},\"safe\":\"0\"}
#enterprise.wechat.user.send.msg={\"touser\":\"$toUser\",\"agentid\":\"$agentId\",\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"$msg\"}} #enterprise.wechat.user.send.msg={\"touser\":\"$toUser\",\"agentid\":\"$agentId\",\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"$msg\"}}
plugin.dir=/Users/xx/your/path/to/plugin/dir

80
dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPluginTest.java

@ -0,0 +1,80 @@
/*
* 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.plugin;
import org.apache.dolphinscheduler.alert.utils.Constants;
import org.apache.dolphinscheduler.common.enums.ShowType;
import org.apache.dolphinscheduler.plugin.api.AlertPlugin;
import org.apache.dolphinscheduler.plugin.model.AlertData;
import org.apache.dolphinscheduler.plugin.model.AlertInfo;
import org.apache.dolphinscheduler.plugin.model.PluginName;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
public class EmailAlertPluginTest {
private static final Logger logger = LoggerFactory.getLogger(EmailAlertPluginTest.class);
private AlertPlugin plugin;
@Before
public void before() {
plugin = new EmailAlertPlugin();
}
@Test
public void getId() {
String id = plugin.getId();
assertEquals(Constants.PLUGIN_DEFAULT_EMAIL, id);
}
@Test
public void getName() {
PluginName pluginName = plugin.getName();
assertEquals(Constants.PLUGIN_DEFAULT_EMAIL_CH, pluginName.getChinese());
assertEquals(Constants.PLUGIN_DEFAULT_EMAIL_EN, pluginName.getEnglish());
}
@Test
public void process() {
AlertInfo alertInfo = new AlertInfo();
AlertData alertData = new AlertData();
alertData.setId(1)
.setAlertGroupId(1)
.setContent("[\"alarm time:2018-02-05\", \"service name:MYSQL_ALTER\", \"alarm name:MYSQL_ALTER_DUMP\", " +
"\"get the alarm exception.!,interface error,exception information:timed out\", \"request address:http://blog.csdn.net/dreamInTheWorld/article/details/78539286\"]")
.setLog("test log")
.setReceivers("xx@xx.com")
.setReceiversCc("xx@xx.com")
.setShowType(ShowType.TEXT.getDescp())
.setTitle("test title");
alertInfo.setAlertData(alertData);
List<String> list = new ArrayList<String>(){{ add("xx@xx.com"); }};
alertInfo.addProp("receivers", list);
Map<String, Object> ret = plugin.process(alertInfo);
assertFalse(Boolean.parseBoolean(String.valueOf(ret.get(Constants.STATUS))));
}
}

13
dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java

@ -20,6 +20,7 @@ import com.alibaba.fastjson.JSON;
import org.apache.dolphinscheduler.common.enums.AlertType; import org.apache.dolphinscheduler.common.enums.AlertType;
import org.apache.dolphinscheduler.common.enums.ShowType; import org.apache.dolphinscheduler.common.enums.ShowType;
import org.apache.dolphinscheduler.dao.entity.Alert; import org.apache.dolphinscheduler.dao.entity.Alert;
import org.apache.dolphinscheduler.plugin.model.AlertData;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
@ -120,14 +121,22 @@ public class EnterpriseWeChatUtilsTest {
@Test @Test
public void testMarkdownByAlertForText(){ public void testMarkdownByAlertForText(){
Alert alertForText = createAlertForText(); Alert alertForText = createAlertForText();
String result = EnterpriseWeChatUtils.markdownByAlert(alertForText); AlertData alertData = new AlertData();
alertData.setTitle(alertForText.getTitle())
.setShowType(alertForText.getShowType().getDescp())
.setContent(alertForText.getContent());
String result = EnterpriseWeChatUtils.markdownByAlert(alertData);
Assert.assertNotNull(result); Assert.assertNotNull(result);
} }
@Test @Test
public void testMarkdownByAlertForTable(){ public void testMarkdownByAlertForTable(){
Alert alertForText = createAlertForTable(); Alert alertForText = createAlertForTable();
String result = EnterpriseWeChatUtils.markdownByAlert(alertForText); AlertData alertData = new AlertData();
alertData.setTitle(alertForText.getTitle())
.setShowType(alertForText.getShowType().getDescp())
.setContent(alertForText.getContent());
String result = EnterpriseWeChatUtils.markdownByAlert(alertData);
Assert.assertNotNull(result); Assert.assertNotNull(result);
} }

10
dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java

@ -58,7 +58,7 @@ public class MailUtilsTest {
alert.setAlertType(AlertType.EMAIL); alert.setAlertType(AlertType.EMAIL);
alert.setAlertGroupId(4); alert.setAlertGroupId(4);
MailUtils.sendMails(Arrays.asList(receivers),Arrays.asList(receiversCc),alert.getTitle(),alert.getContent(), ShowType.TEXT); MailUtils.sendMails(Arrays.asList(receivers),Arrays.asList(receiversCc),alert.getTitle(),alert.getContent(), ShowType.TEXT.getDescp());
} }
@ -70,7 +70,7 @@ public class MailUtilsTest {
String[] mails = new String[]{"xx@xx.com"}; String[] mails = new String[]{"xx@xx.com"};
for(Alert alert : alerts){ for(Alert alert : alerts){
MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), alert.getShowType()); MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE.getDescp());
} }
} }
@ -111,7 +111,7 @@ public class MailUtilsTest {
alert.setContent(content); alert.setContent(content);
alert.setAlertType(AlertType.EMAIL); alert.setAlertType(AlertType.EMAIL);
alert.setAlertGroupId(1); alert.setAlertGroupId(1);
MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE); MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE.getDescp());
} }
/** /**
@ -170,7 +170,7 @@ public class MailUtilsTest {
alert.setContent(content); alert.setContent(content);
alert.setAlertType(AlertType.EMAIL); alert.setAlertType(AlertType.EMAIL);
alert.setAlertGroupId(1); alert.setAlertGroupId(1);
MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.ATTACHMENT); MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.ATTACHMENT.getDescp());
} }
@Test @Test
@ -183,7 +183,7 @@ public class MailUtilsTest {
alert.setContent(content); alert.setContent(content);
alert.setAlertType(AlertType.EMAIL); alert.setAlertType(AlertType.EMAIL);
alert.setAlertGroupId(1); alert.setAlertGroupId(1);
MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.TABLEATTACHMENT); MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.TABLEATTACHMENT.getDescp());
} }
} }

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

@ -21,6 +21,7 @@ import org.apache.dolphinscheduler.api.enums.ExecuteType;
import org.apache.dolphinscheduler.api.enums.Status; import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.*; import org.apache.dolphinscheduler.common.enums.*;
import org.apache.dolphinscheduler.common.model.Server;
import org.apache.dolphinscheduler.common.utils.CollectionUtils; import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.DateUtils; import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtils; import org.apache.dolphinscheduler.common.utils.JSONUtils;
@ -59,7 +60,7 @@ public class ExecutorService extends BaseService{
private ProcessDefinitionMapper processDefinitionMapper; private ProcessDefinitionMapper processDefinitionMapper;
@Autowired @Autowired
private ProcessDefinitionService processDefinitionService; private MonitorService monitorService;
@Autowired @Autowired
@ -123,6 +124,14 @@ public class ExecutorService extends BaseService{
return result; return result;
} }
// check master server exists
List<Server> masterServers = monitorService.getServerListFromZK(true);
if (masterServers.size() == 0) {
putMsg(result, Status.MASTER_NOT_EXISTS);
return result;
}
/** /**
* create command * create command
*/ */

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

@ -365,6 +365,7 @@ public class SchedulerService extends BaseService {
if (masterServers.size() == 0) { if (masterServers.size() == 0) {
putMsg(result, Status.MASTER_NOT_EXISTS); putMsg(result, Status.MASTER_NOT_EXISTS);
return result;
} }
// set status // set status

14
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/ZooKeeperState.java

@ -33,7 +33,7 @@ public class ZooKeeperState {
private final String host; private final String host;
private final int port; private final int port;
private int minLatency = -1, avgLatency = -1, maxLatency = -1; private float minLatency = -1, avgLatency = -1, maxLatency = -1;
private long received = -1; private long received = -1;
private long sent = -1; private long sent = -1;
private int outStanding = -1; private int outStanding = -1;
@ -60,9 +60,9 @@ public class ZooKeeperState {
String line = scannerForStat.nextLine(); String line = scannerForStat.nextLine();
if (line.startsWith("Latency min/avg/max:")) { if (line.startsWith("Latency min/avg/max:")) {
String[] latencys = getStringValueFromLine(line).split("/"); String[] latencys = getStringValueFromLine(line).split("/");
minLatency = Integer.parseInt(latencys[0]); minLatency = Float.parseFloat(latencys[0]);
avgLatency = Integer.parseInt(latencys[1]); avgLatency = Float.parseFloat(latencys[1]);
maxLatency = Integer.parseInt(latencys[2]); maxLatency = Float.parseFloat(latencys[2]);
} else if (line.startsWith("Received:")) { } else if (line.startsWith("Received:")) {
received = Long.parseLong(getStringValueFromLine(line)); received = Long.parseLong(getStringValueFromLine(line));
} else if (line.startsWith("Sent:")) { } else if (line.startsWith("Sent:")) {
@ -165,15 +165,15 @@ public class ZooKeeperState {
return port; return port;
} }
public int getMinLatency() { public float getMinLatency() {
return minLatency; return minLatency;
} }
public int getAvgLatency() { public float getAvgLatency() {
return avgLatency; return avgLatency;
} }
public int getMaxLatency() { public float getMaxLatency() {
return maxLatency; return maxLatency;
} }

6
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/ZookeeperMonitor.java

@ -88,9 +88,9 @@ public class ZookeeperMonitor extends AbstractZKClient {
long sent = state.getSent(); long sent = state.getSent();
long received = state.getReceived(); long received = state.getReceived();
String mode = state.getMode(); String mode = state.getMode();
int minLatency = state.getMinLatency(); float minLatency = state.getMinLatency();
int avgLatency = state.getAvgLatency(); float avgLatency = state.getAvgLatency();
int maxLatency = state.getMaxLatency(); float maxLatency = state.getMaxLatency();
int nodeCount = state.getNodeCount(); int nodeCount = state.getNodeCount();
int status = ok ? 1 : 0; int status = ok ? 1 : 0;
Date date = new Date(); Date date = new Date();

43
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ExecutorService2Test.java

@ -22,6 +22,7 @@ import org.apache.dolphinscheduler.common.enums.CommandType;
import org.apache.dolphinscheduler.common.enums.Priority; import org.apache.dolphinscheduler.common.enums.Priority;
import org.apache.dolphinscheduler.common.enums.ReleaseState; import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.common.enums.RunMode; import org.apache.dolphinscheduler.common.enums.RunMode;
import org.apache.dolphinscheduler.common.model.Server;
import org.apache.dolphinscheduler.dao.entity.*; import org.apache.dolphinscheduler.dao.entity.*;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper; import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper; import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
@ -63,6 +64,9 @@ public class ExecutorService2Test {
@Mock @Mock
private ProjectService projectService; private ProjectService projectService;
@Mock
private MonitorService monitorService;
private int processDefinitionId = 1; private int processDefinitionId = 1;
private int tenantId = 1; private int tenantId = 1;
@ -102,6 +106,7 @@ public class ExecutorService2Test {
Mockito.when(processDefinitionMapper.selectById(processDefinitionId)).thenReturn(processDefinition); Mockito.when(processDefinitionMapper.selectById(processDefinitionId)).thenReturn(processDefinition);
Mockito.when(processService.getTenantForProcess(tenantId, userId)).thenReturn(new Tenant()); Mockito.when(processService.getTenantForProcess(tenantId, userId)).thenReturn(new Tenant());
Mockito.when(processService.createCommand(any(Command.class))).thenReturn(1); Mockito.when(processService.createCommand(any(Command.class))).thenReturn(1);
Mockito.when(monitorService.getServerListFromZK(true)).thenReturn(getMasterServersList());
} }
/** /**
@ -121,7 +126,6 @@ public class ExecutorService2Test {
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
verify(processService, times(1)).createCommand(any(Command.class)); verify(processService, times(1)).createCommand(any(Command.class));
}catch (Exception e){ }catch (Exception e){
Assert.assertTrue(false);
} }
} }
@ -142,7 +146,6 @@ public class ExecutorService2Test {
Assert.assertEquals(Status.START_PROCESS_INSTANCE_ERROR, result.get(Constants.STATUS)); Assert.assertEquals(Status.START_PROCESS_INSTANCE_ERROR, result.get(Constants.STATUS));
verify(processService, times(0)).createCommand(any(Command.class)); verify(processService, times(0)).createCommand(any(Command.class));
}catch (Exception e){ }catch (Exception e){
Assert.assertTrue(false);
} }
} }
@ -163,7 +166,6 @@ public class ExecutorService2Test {
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
verify(processService, times(1)).createCommand(any(Command.class)); verify(processService, times(1)).createCommand(any(Command.class));
}catch (Exception e){ }catch (Exception e){
Assert.assertTrue(false);
} }
} }
@ -184,7 +186,6 @@ public class ExecutorService2Test {
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
verify(processService, times(31)).createCommand(any(Command.class)); verify(processService, times(31)).createCommand(any(Command.class));
}catch (Exception e){ }catch (Exception e){
Assert.assertTrue(false);
} }
} }
@ -205,10 +206,42 @@ public class ExecutorService2Test {
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
verify(processService, times(15)).createCommand(any(Command.class)); verify(processService, times(15)).createCommand(any(Command.class));
}catch (Exception e){ }catch (Exception e){
Assert.assertTrue(false);
} }
} }
@Test
public void testNoMsterServers() throws ParseException{
Mockito.when(monitorService.getServerListFromZK(true)).thenReturn(new ArrayList<Server>());
Map<String, Object> result = executorService.execProcessInstance(loginUser, projectName,
processDefinitionId, cronTime, CommandType.COMPLEMENT_DATA,
null, null,
null, null, 0,
"", "", RunMode.RUN_MODE_PARALLEL,
Priority.LOW, Constants.DEFAULT_WORKER_GROUP, 110);
Assert.assertEquals(result.get(Constants.STATUS),Status.MASTER_NOT_EXISTS);
}
private List<Server> getMasterServersList(){
List<Server> masterServerList = new ArrayList<>();
Server masterServer1 = new Server();
masterServer1.setId(1);
masterServer1.setHost("192.168.220.188");
masterServer1.setPort(1121);
masterServerList.add(masterServer1);
Server masterServer2 = new Server();
masterServer2.setId(2);
masterServer2.setHost("192.168.220.189");
masterServer2.setPort(1122);
masterServerList.add(masterServer2);
return masterServerList;
}
private List<Schedule> zeroSchedulerList(){ private List<Schedule> zeroSchedulerList(){
return Collections.EMPTY_LIST; return Collections.EMPTY_LIST;
} }

5
dolphinscheduler-common/pom.xml

@ -32,12 +32,15 @@
<codehaus.janino.version>3.1.0</codehaus.janino.version> <codehaus.janino.version>3.1.0</codehaus.janino.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-plugin-api</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>

7
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java

@ -954,4 +954,11 @@ public final class Constants {
* authorize readable perm * authorize readable perm
*/ */
public static final int AUTHORIZE_READABLE_PERM=4; public static final int AUTHORIZE_READABLE_PERM=4;
/**
* plugin configurations
*/
public static final String PLUGIN_JAR_SUFFIX = ".jar";
} }

107
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/FilePluginManager.java

@ -0,0 +1,107 @@
/*
* 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.common.plugin;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.plugin.api.AlertPlugin;
import org.apache.dolphinscheduler.plugin.spi.AlertPluginProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;
/**
* FilePluginManager
*/
public class FilePluginManager implements PluginManager {
private static final Logger logger = LoggerFactory.getLogger(FilePluginManager.class);
private Map<String, AlertPlugin> pluginMap = new ConcurrentHashMap<>();
private Map<String, ServiceLoader<AlertPluginProvider>> pluginLoaderMap = new ConcurrentHashMap<>();
private Map<String, PluginClassLoader> classLoaderMap = new ConcurrentHashMap<>();
private String[] whitePrefixes;
private String[] excludePrefixes;
public FilePluginManager(String dirPath, String[] whitePrefixes, String[] excludePrefixes) {
this.whitePrefixes = whitePrefixes;
this.excludePrefixes = excludePrefixes;
try {
load(dirPath);
} catch (MalformedURLException e) {
logger.error("load plugins failed.", e);
}
}
private void load(String dirPath) throws MalformedURLException {
logger.info("start to load jar files in {}", dirPath);
if (dirPath == null) {
logger.error("not a valid path - {}", dirPath);
return;
}
File[] files = new File(dirPath).listFiles();
if (files == null) {
logger.error("not a valid path - {}", dirPath);
return;
}
for (File file : files) {
if (file.isDirectory() && !file.getPath().endsWith(Constants.PLUGIN_JAR_SUFFIX)) {
continue;
}
String pluginName = file.getName()
.substring(0, file.getName().length() - Constants.PLUGIN_JAR_SUFFIX.length());
URL[] urls = new URL[]{ file.toURI().toURL() };
PluginClassLoader classLoader =
new PluginClassLoader(urls, Thread.currentThread().getContextClassLoader(), whitePrefixes, excludePrefixes);
classLoaderMap.put(pluginName, classLoader);
ServiceLoader<AlertPluginProvider> loader = ServiceLoader.load(AlertPluginProvider.class, classLoader);
pluginLoaderMap.put(pluginName, loader);
loader.forEach(provider -> {
AlertPlugin plugin = provider.createPlugin();
pluginMap.put(plugin.getId(), plugin);
logger.info("loaded plugin - {}", plugin.getId());
});
}
}
@Override
public AlertPlugin findOne(String name) {
return pluginMap.get(name);
}
@Override
public Map<String, AlertPlugin> findAll() {
return pluginMap;
}
@Override
public void addPlugin(AlertPlugin plugin) {
pluginMap.put(plugin.getId(), plugin);
}
}

154
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginClassLoader.java

@ -0,0 +1,154 @@
/*
* 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.common.plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Plugin Class Loader
*/
public class PluginClassLoader extends URLClassLoader {
private static final Logger logger = LoggerFactory.getLogger(PluginClassLoader.class);
private static final String JAVA_PACKAGE_PREFIX = "java.";
private static final String JAVAX_PACKAGE_PREFIX = "javax.";
private final String[] whitePrefixes;
private final String[] excludePrefixes;
public PluginClassLoader(URL[] urls, ClassLoader parent, String[] whitePrefix, String[] excludePreifx) {
super(urls, parent);
this.whitePrefixes = whitePrefix;
this.excludePrefixes = excludePreifx;
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
logger.trace("Received request to load class '{}'", name);
synchronized (getClassLoadingLock(name)) {
if (name.startsWith(JAVA_PACKAGE_PREFIX) || name.startsWith(JAVAX_PACKAGE_PREFIX)) {
return findSystemClass(name);
}
boolean isWhitePrefixes = fromWhitePrefix(name);
boolean isExcludePrefixed = fromExcludePrefix(name);
// if the class is part of the plugin engine use parent class loader
if (!isWhitePrefixes && isExcludePrefixed) {
return getParent().loadClass(name);
}
// check whether it's already been loaded
Class<?> loadedClass = findLoadedClass(name);
if (loadedClass != null) {
logger.debug("Found loaded class '{}'", name);
return loadedClass;
}
// nope, try to load locally
try {
loadedClass = findClass(name);
logger.debug("Found class '{}' in plugin classpath", name);
return loadedClass;
} catch (ClassNotFoundException e) {
// try next step
}
// use the standard ClassLoader (which follows normal parent delegation)
return super.loadClass(name);
}
}
private boolean fromWhitePrefix(String name) {
if (this.whitePrefixes == null) {
return false;
}
for (String whitePrefix : this.whitePrefixes) {
if (name.startsWith(whitePrefix)) {
return true;
}
}
return false;
}
private boolean fromExcludePrefix(String name) {
if (this.excludePrefixes == null) {
return false;
}
for (String excludePrefix : this.excludePrefixes) {
if (name.startsWith(excludePrefix)) {
return true;
}
}
return false;
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
List<URL> allRes = new LinkedList<>();
Enumeration<URL> thisRes = findResources(name);
if (thisRes != null) {
while (thisRes.hasMoreElements()) {
allRes.add(thisRes.nextElement());
}
}
Enumeration<URL> parentRes = super.findResources(name);
if (parentRes != null) {
while (parentRes.hasMoreElements()) {
allRes.add(parentRes.nextElement());
}
}
return new Enumeration<URL>() {
Iterator<URL> it = allRes.iterator();
@Override
public boolean hasMoreElements() {
return it.hasNext();
}
@Override
public URL nextElement() {
return it.next();
}
};
}
@Override
public URL getResource(String name) {
URL res = null;
res = findResource(name);
if (res == null) {
res = super.getResource(name);
}
return res;
}
}

33
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginManager.java

@ -0,0 +1,33 @@
/*
* 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.common.plugin;
import org.apache.dolphinscheduler.plugin.api.AlertPlugin;
import java.util.Map;
/**
* PluginManager
*/
public interface PluginManager {
AlertPlugin findOne(String name);
Map<String, AlertPlugin> findAll();
void addPlugin(AlertPlugin plugin);
}

9
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/HadoopUtils.java

@ -503,6 +503,9 @@ public class HadoopUtils implements Closeable {
* @return hdfs file name * @return hdfs file name
*/ */
public static String getHdfsFileName(ResourceType resourceType, String tenantCode, String fileName) { public static String getHdfsFileName(ResourceType resourceType, String tenantCode, String fileName) {
if (fileName.startsWith("/")) {
fileName = fileName.replaceFirst("/","");
}
return String.format("%s/%s", getHdfsDir(resourceType,tenantCode), fileName); return String.format("%s/%s", getHdfsDir(resourceType,tenantCode), fileName);
} }
@ -514,6 +517,9 @@ public class HadoopUtils implements Closeable {
* @return get absolute path and name for file on hdfs * @return get absolute path and name for file on hdfs
*/ */
public static String getHdfsResourceFileName(String tenantCode, String fileName) { public static String getHdfsResourceFileName(String tenantCode, String fileName) {
if (fileName.startsWith("/")) {
fileName = fileName.replaceFirst("/","");
}
return String.format("%s/%s", getHdfsResDir(tenantCode), fileName); return String.format("%s/%s", getHdfsResDir(tenantCode), fileName);
} }
@ -525,6 +531,9 @@ public class HadoopUtils implements Closeable {
* @return get absolute path and name for udf file on hdfs * @return get absolute path and name for udf file on hdfs
*/ */
public static String getHdfsUdfFileName(String tenantCode, String fileName) { public static String getHdfsUdfFileName(String tenantCode, String fileName) {
if (fileName.startsWith("/")) {
fileName = fileName.replaceFirst("/","");
}
return String.format("%s/%s", getHdfsUdfDir(tenantCode), fileName); return String.format("%s/%s", getHdfsUdfDir(tenantCode), fileName);
} }

72
dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/plugin/FilePluginManagerTest.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.common.plugin;
import org.apache.dolphinscheduler.plugin.api.AlertPlugin;
import org.apache.dolphinscheduler.plugin.model.AlertInfo;
import org.apache.dolphinscheduler.plugin.model.PluginName;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
public class FilePluginManagerTest {
private FilePluginManager filePluginManager;
private AlertPlugin alertPlugin;
@Before
public void before() {
filePluginManager = new FilePluginManager(null, null, null);
alertPlugin = new AlertPlugin() {
@Override
public String getId() {
return "test";
}
@Override
public PluginName getName() {
return new PluginName().setChinese("ch").setEnglish("en");
}
@Override
public Map<String, Object> process(AlertInfo info) {
return new HashMap<>();
}
};
}
@Test
public void findOne() {
filePluginManager.addPlugin(alertPlugin);
assertEquals(alertPlugin, filePluginManager.findOne(alertPlugin.getId()));
}
@Test
public void findAll() {
assertNotNull(filePluginManager.findAll());
}
@Test
public void addPlugin() {
filePluginManager.addPlugin(alertPlugin);
assertNotNull(filePluginManager.findAll());
}
}

61
dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/plugin/PluginClassLoaderTest.java

@ -0,0 +1,61 @@
/*
* 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.common.plugin;
import org.junit.Before;
import org.junit.Test;
import java.net.URL;
import static org.junit.Assert.*;
public class PluginClassLoaderTest {
private PluginClassLoader pluginClassLoader;
private ClassLoader parent;
@Before
public void setUp() {
parent = Thread.currentThread().getContextClassLoader();
pluginClassLoader = new PluginClassLoader(
new URL[]{}, parent,
null, null);
}
@Test
public void loadClassNull() {
Class clazz = null;
try {
clazz = pluginClassLoader.loadClass("java.lang.Object");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
assertEquals(null, clazz.getClassLoader());
}
@Test
public void loadClassApp() {
Class clazz = null;
try {
clazz = pluginClassLoader.loadClass("org.apache.dolphinscheduler.common.Constants");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
assertEquals(parent, clazz.getClassLoader());
}
}

12
dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/HadoopUtilsTest.java

@ -127,6 +127,18 @@ public class HadoopUtilsTest {
Assert.assertEquals("/dolphinscheduler/11000/resources/aa.txt", result); Assert.assertEquals("/dolphinscheduler/11000/resources/aa.txt", result);
} }
@Test
public void getHdfsResourceFileName() {
String result = hadoopUtils.getHdfsResourceFileName("11000","aa.txt");
Assert.assertEquals("/dolphinscheduler/11000/resources/aa.txt", result);
}
@Test
public void getHdfsUdfFileName() {
String result = hadoopUtils.getHdfsFileName(ResourceType.UDF,"11000","aa.txt");
Assert.assertEquals("/dolphinscheduler/11000/udfs/aa.txt", result);
}
@Test @Test
public void isYarnEnabled() { public void isYarnEnabled() {
boolean result = hadoopUtils.isYarnEnabled(); boolean result = hadoopUtils.isYarnEnabled();

18
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/ZookeeperRecord.java

@ -56,17 +56,17 @@ public class ZookeeperRecord {
/** /**
* min Latency * min Latency
*/ */
private int minLatency; private float minLatency;
/** /**
* avg Latency * avg Latency
*/ */
private int avgLatency; private float avgLatency;
/** /**
* max Latency * max Latency
*/ */
private int maxLatency; private float maxLatency;
/** /**
* node count * node count
@ -85,7 +85,7 @@ public class ZookeeperRecord {
private int state; private int state;
public ZookeeperRecord(String hostname,int connections, int watches, long sent, long received, String mode, int minLatency, int avgLatency, int maxLatency, int nodeCount, int state,Date date) { public ZookeeperRecord(String hostname,int connections, int watches, long sent, long received, String mode, float minLatency, float avgLatency, float maxLatency, int nodeCount, int state,Date date) {
this.hostname = hostname; this.hostname = hostname;
this.connections = connections; this.connections = connections;
this.watches = watches; this.watches = watches;
@ -149,23 +149,23 @@ public class ZookeeperRecord {
this.mode = mode; this.mode = mode;
} }
public int getMinLatency() { public float getMinLatency() {
return minLatency; return minLatency;
} }
public void setMinLatency(int minLatency) { public void setMinLatency(float minLatency) {
this.minLatency = minLatency; this.minLatency = minLatency;
} }
public int getAvgLatency() { public float getAvgLatency() {
return avgLatency; return avgLatency;
} }
public void setAvgLatency(int avgLatency) { public void setAvgLatency(float avgLatency) {
this.avgLatency = avgLatency; this.avgLatency = avgLatency;
} }
public int getMaxLatency() { public float getMaxLatency() {
return maxLatency; return maxLatency;
} }

1
dolphinscheduler-dist/release-docs/LICENSE vendored

@ -474,7 +474,6 @@ The following components are provided under a MIT 2.0 license. See project link
The text of each license is also included at licenses/LICENSE-[project].txt. The text of each license is also included at licenses/LICENSE-[project].txt.
jul-to-slf4j 1.7.25: https://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j/1.7.25, MIT jul-to-slf4j 1.7.25: https://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j/1.7.25, MIT
lombok 1.18.6: https://mvnrepository.com/artifact/org.projectlombok/lombok/1.18.6, MIT
mssql-jdbc 6.1.0.jre8: https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc/6.1.0.jre8, MIT mssql-jdbc 6.1.0.jre8: https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc/6.1.0.jre8, MIT
slf4j-api 1.7.5: https://mvnrepository.com/artifact/org.slf4j/slf4j-api/1.7.5, MIT slf4j-api 1.7.5: https://mvnrepository.com/artifact/org.slf4j/slf4j-api/1.7.5, MIT

19
dolphinscheduler-dist/release-docs/licenses/LICENSE-lombok.txt vendored

@ -1,19 +0,0 @@
Copyright (C) 2009-2015 The Project Lombok Authors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

52
dolphinscheduler-plugin-api/pom.xml

@ -0,0 +1,52 @@
<?xml version="1.0"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler</artifactId>
<version>1.2.1-SNAPSHOT</version>
</parent>
<artifactId>dolphinscheduler-plugin-api</artifactId>
<name>${project.artifactId}</name>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
</dependencies>
</project>

45
dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/api/AlertPlugin.java

@ -0,0 +1,45 @@
/*
* 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.plugin.api;
import org.apache.dolphinscheduler.plugin.model.AlertInfo;
import org.apache.dolphinscheduler.plugin.model.PluginName;
import java.util.Map;
/**
* Plugin
*/
public interface AlertPlugin {
/**
* Get alert plugin id
*
* @return alert plugin id, which should be unique
*/
String getId();
/**
* Get alert plugin name, which will show in front end portal
*
* @return plugin name
*/
PluginName getName();
Map<String, Object> process(AlertInfo info);
}

129
dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertData.java

@ -0,0 +1,129 @@
/*
* 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.plugin.model;
/**
* AlertData
*/
public class AlertData {
/**
* alert primary key
*/
private int id;
/**
* title
*/
private String title;
/**
* content
*/
private String content;
/**
* log
*/
private String log;
/**
* alertgroup_id
*/
private int alertGroupId;
/**
* receivers
*/
private String receivers;
/**
* show_type
*/
private String showType;
/**
* receivers_cc
*/
private String receiversCc;
public int getId() {
return id;
}
public AlertData setId(int id) {
this.id = id;
return this;
}
public String getTitle() {
return title;
}
public AlertData setTitle(String title) {
this.title = title;
return this;
}
public String getContent() {
return content;
}
public AlertData setContent(String content) {
this.content = content;
return this;
}
public String getLog() {
return log;
}
public AlertData setLog(String log) {
this.log = log;
return this;
}
public int getAlertGroupId() {
return alertGroupId;
}
public AlertData setAlertGroupId(int alertGroupId) {
this.alertGroupId = alertGroupId;
return this;
}
public String getReceivers() {
return receivers;
}
public AlertData setReceivers(String receivers) {
this.receivers = receivers;
return this;
}
public String getReceiversCc() {
return receiversCc;
}
public AlertData setReceiversCc(String receiversCc) {
this.receiversCc = receiversCc;
return this;
}
public String getShowType() {
return showType;
}
public AlertData setShowType(String showType) {
this.showType = showType;
return this;
}
}

61
dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertInfo.java

@ -0,0 +1,61 @@
/*
* 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.plugin.model;
import java.util.HashMap;
import java.util.Map;
/**
* AlertInfo
*/
public class AlertInfo {
private Map<String, Object> alertProps;
private AlertData alertData;
public AlertInfo() {
this.alertProps = new HashMap<>();
}
public Map<String, Object> getAlertProps() {
return alertProps;
}
public AlertInfo setAlertProps(Map<String, Object> alertProps) {
this.alertProps = alertProps;
return this;
}
public AlertInfo addProp(String key, Object value) {
this.alertProps.put(key, value);
return this;
}
public Object getProp(String key) {
return this.alertProps.get(key);
}
public AlertData getAlertData() {
return alertData;
}
public AlertInfo setAlertData(AlertData alertData) {
this.alertData = alertData;
return this;
}
}

45
dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/PluginName.java

@ -0,0 +1,45 @@
/*
* 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.plugin.model;
/**
* PluginName
*/
public class PluginName {
private String chinese;
private String english;
public String getChinese() {
return chinese;
}
public PluginName setChinese(String chinese) {
this.chinese = chinese;
return this;
}
public String getEnglish() {
return english;
}
public PluginName setEnglish(String english) {
this.english = english;
return this;
}
}

33
dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/spi/AlertPluginProvider.java

@ -0,0 +1,33 @@
/*
* 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.plugin.spi;
import org.apache.dolphinscheduler.plugin.api.AlertPlugin;
/**
* PluginProvider
*/
public interface AlertPluginProvider {
/**
* create an alert plugin
*
* @return an alert plugin
*/
AlertPlugin createPlugin();
}

190
dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtils.java

@ -0,0 +1,190 @@
/*
* 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.plugin.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;
/**
* property utils
* single instance
*/
public class PropertyUtils {
private static final Logger logger = LoggerFactory.getLogger(PropertyUtils.class);
private static final Properties properties = new Properties();
private PropertyUtils() {
throw new IllegalStateException("PropertyUtils class");
}
static {
String propertyFiles = "/plugin.properties";
InputStream fis = null;
try {
fis = PropertyUtils.class.getResourceAsStream(propertyFiles);
properties.load(fis);
} catch (IOException e) {
logger.error(e.getMessage(), e);
if (fis != null) {
IOUtils.closeQuietly(fis);
}
} finally {
IOUtils.closeQuietly(fis);
}
}
/**
* get property value
*
* @param key property name
* @param defaultVal default value
* @return property value
*/
public static String getString(String key, String defaultVal) {
String val = properties.getProperty(key.trim());
return val == null ? defaultVal : val;
}
/**
* get property value
*
* @param key property name
* @return property value
*/
public static String getString(String key) {
if (key == null) {
return null;
}
return properties.getProperty(key.trim());
}
/**
* 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);
}
/**
* get int
*
* @param key key
* @param defaultValue default value
* @return property value
*/
public static int getInt(String key, int defaultValue) {
String value = properties.getProperty(key.trim());
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 property value
*/
public static boolean getBoolean(String key) {
String value = properties.getProperty(key.trim());
if (value == null) {
return false;
}
return Boolean.parseBoolean(value);
}
/**
* get property value
*
* @param key property name
* @param defaultValue default value
* @return property value
*/
public static Boolean getBoolean(String key, boolean defaultValue) {
String value = properties.getProperty(key.trim());
if (value == null) {
return defaultValue;
}
return Boolean.parseBoolean(value);
}
/**
* get property long value
*
* @param key key
* @param defaultVal default value
* @return property value
*/
public static long getLong(String key, long defaultVal) {
String val = getString(key);
return val == null ? defaultVal : Long.parseLong(val);
}
/**
* get long
*
* @param key key
* @return property value
*/
public static long getLong(String key) {
return getLong(key, -1);
}
/**
* get double
*
* @param key key
* @param defaultVal default value
* @return property value
*/
public static double getDouble(String key, double defaultVal) {
String val = properties.getProperty(key.trim());
return val == null ? defaultVal : Double.parseDouble(val);
}
/**
* @param key key
* @param type type
* @param defaultValue default value
* @param <T> T
* @return get enum value
*/
public <T extends Enum<T>> T getEnum(String key, Class<T> type,
T defaultValue) {
String val = properties.getProperty(key.trim());
return val == null ? defaultValue : Enum.valueOf(type, val);
}
}

80
dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/model/AlertDataTest.java

@ -0,0 +1,80 @@
/*
* 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.plugin.model;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class AlertDataTest {
private AlertData alertData;
@Before
public void before() {
alertData = new AlertData();
alertData.setId(1)
.setContent("content")
.setShowType("email")
.setTitle("title")
.setReceivers("receivers")
.setReceiversCc("cc")
.setLog("log")
.setAlertGroupId(1);
}
@Test
public void getId() {
assertEquals(1, alertData.getId());
}
@Test
public void getTitle() {
assertEquals("title", alertData.getTitle());
}
@Test
public void getContent() {
assertEquals("content", alertData.getContent());
}
@Test
public void getLog() {
assertEquals("log", alertData.getLog());
}
@Test
public void getAlertGroupId() {
assertEquals(1, alertData.getAlertGroupId());
}
@Test
public void getReceivers() {
assertEquals("receivers", alertData.getReceivers());
}
@Test
public void getReceiversCc() {
assertEquals("cc", alertData.getReceiversCc());
}
@Test
public void getShowType() {
assertEquals("email", alertData.getShowType());
}
}

54
dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/model/AlertInfoTest.java

@ -0,0 +1,54 @@
/*
* 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.plugin.model;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
public class AlertInfoTest {
private AlertInfo alertInfo;
@Before
public void before() {
alertInfo = new AlertInfo();
}
@Test
public void getAlertProps() {
Map<String, Object> map = new HashMap<>();
alertInfo.setAlertProps(map);
assertNotNull(alertInfo.getAlertProps());
}
@Test
public void getProp() {
alertInfo.addProp("k", "v");
assertEquals("v", alertInfo.getProp("k"));
}
@Test
public void getAlertData() {
alertInfo.setAlertData(new AlertData());
assertNotNull(alertInfo.getAlertData());
}
}

83
dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtilsTest.java

@ -0,0 +1,83 @@
/*
* 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.plugin.utils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.*;
public class PropertyUtilsTest {
private static final Logger logger = LoggerFactory.getLogger(PropertyUtilsTest.class);
/**
* Test getString
*/
@Test
public void testGetString() {
String result = PropertyUtils.getString("test.string");
logger.info(result);
assertEquals("teststring", result);
//If key is null, then return null
result = PropertyUtils.getString(null);
assertNull(result);
}
/**
* Test getBoolean
*/
@Test
public void testGetBoolean() {
//Expected true
Boolean result = PropertyUtils.getBoolean("test.true");
assertTrue(result);
//Expected false
result = PropertyUtils.getBoolean("test.false");
assertFalse(result);
}
/**
* Test getLong
*/
@Test
public void testGetLong() {
long result = PropertyUtils.getLong("test.long");
assertSame(100L, result);
}
/**
* Test getDouble
*/
@Test
public void testGetDouble() {
//If key is undefine in alert.properties, and there is a defaultval, then return defaultval
double result = PropertyUtils.getDouble("abc", 5.0);
assertEquals(5.0, result, 0);
result = PropertyUtils.getDouble("cba", 5.0);
assertEquals(3.1, result, 0.01);
}
}

8
ambari_plugin/common-services/DOLPHIN/2.0.0/package/templates/alert.properties.j2 → dolphinscheduler-plugin-api/src/test/resources/plugin.properties

@ -15,6 +15,8 @@
# limitations under the License. # limitations under the License.
# #
{% for key, value in dolphin_alert_map.iteritems() -%} test.string=teststring
{{key}}={{value}} test.false=false
{% endfor %} test.true=true
cba=3.1
test.long=100

16
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/consumer/TaskPriorityQueueConsumer.java

@ -120,19 +120,31 @@ public class TaskPriorityQueueConsumer extends Thread{
Boolean result = false; Boolean result = false;
while (Stopper.isRunning()){ while (Stopper.isRunning()){
try { try {
result = dispatcher.dispatch(executionContext); result = dispatcher.dispatch(executionContext);
} catch (ExecuteException e) { } catch (ExecuteException e) {
logger.error("dispatch error",e); logger.error("dispatch error",e);
ThreadUtils.sleep(SLEEP_TIME_MILLIS); ThreadUtils.sleep(SLEEP_TIME_MILLIS);
} }
if (result){ if (result || taskInstanceIsFinalState(taskInstanceId)){
break; break;
} }
} }
return result; return result;
} }
/**
* taskInstance is final state
* successfailurekillstoppausethreadwaiting is final state
* @param taskInstanceId taskInstanceId
* @return taskInstance is final state
*/
public Boolean taskInstanceIsFinalState(int taskInstanceId){
TaskInstance taskInstance = processService.findTaskInstanceById(taskInstanceId);
return taskInstance.getState().typeIsFinished();
}
/** /**
* get TaskExecutionContext * get TaskExecutionContext
* @param taskInstanceId taskInstanceId * @param taskInstanceId taskInstanceId

46
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/runner/MasterTaskExecThread.java

@ -26,6 +26,7 @@ import org.apache.dolphinscheduler.common.enums.TaskTimeoutStrategy;
import org.apache.dolphinscheduler.common.model.TaskNode; import org.apache.dolphinscheduler.common.model.TaskNode;
import org.apache.dolphinscheduler.common.task.TaskTimeoutParameter; import org.apache.dolphinscheduler.common.task.TaskTimeoutParameter;
import org.apache.dolphinscheduler.common.thread.Stopper; import org.apache.dolphinscheduler.common.thread.Stopper;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition; import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.TaskInstance; import org.apache.dolphinscheduler.dao.entity.TaskInstance;
import org.apache.dolphinscheduler.remote.command.TaskKillRequestCommand; import org.apache.dolphinscheduler.remote.command.TaskKillRequestCommand;
@ -35,9 +36,12 @@ import org.apache.dolphinscheduler.server.master.cache.impl.TaskInstanceCacheMan
import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext; import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext;
import org.apache.dolphinscheduler.server.master.dispatch.enums.ExecutorType; import org.apache.dolphinscheduler.server.master.dispatch.enums.ExecutorType;
import org.apache.dolphinscheduler.server.master.dispatch.executor.NettyExecutorManager; import org.apache.dolphinscheduler.server.master.dispatch.executor.NettyExecutorManager;
import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter;
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext; import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date; import java.util.Date;
import java.util.Set;
/** /**
@ -53,6 +57,12 @@ public class MasterTaskExecThread extends MasterBaseTaskExecThread {
private NettyExecutorManager nettyExecutorManager; private NettyExecutorManager nettyExecutorManager;
/**
* zookeeper register center
*/
private ZookeeperRegistryCenter zookeeperRegistryCenter;
/** /**
* constructor of MasterTaskExecThread * constructor of MasterTaskExecThread
* @param taskInstance task instance * @param taskInstance task instance
@ -61,6 +71,7 @@ public class MasterTaskExecThread extends MasterBaseTaskExecThread {
super(taskInstance); super(taskInstance);
this.taskInstanceCacheManager = SpringApplicationContext.getBean(TaskInstanceCacheManagerImpl.class); this.taskInstanceCacheManager = SpringApplicationContext.getBean(TaskInstanceCacheManagerImpl.class);
this.nettyExecutorManager = SpringApplicationContext.getBean(NettyExecutorManager.class); this.nettyExecutorManager = SpringApplicationContext.getBean(NettyExecutorManager.class);
this.zookeeperRegistryCenter = SpringApplicationContext.getBean(ZookeeperRegistryCenter.class);
} }
/** /**
@ -175,6 +186,16 @@ public class MasterTaskExecThread extends MasterBaseTaskExecThread {
} }
alreadyKilled = true; alreadyKilled = true;
String taskInstanceWorkerGroup = taskInstance.getWorkerGroup();
// not exists
if (!existsValidWorkerGroup(taskInstanceWorkerGroup)){
taskInstance.setState(ExecutionStatus.KILL);
taskInstance.setEndTime(new Date());
processService.updateTaskInstance(taskInstance);
return;
}
TaskKillRequestCommand killCommand = new TaskKillRequestCommand(); TaskKillRequestCommand killCommand = new TaskKillRequestCommand();
killCommand.setTaskInstanceId(taskInstance.getId()); killCommand.setTaskInstanceId(taskInstance.getId());
@ -185,10 +206,33 @@ public class MasterTaskExecThread extends MasterBaseTaskExecThread {
nettyExecutorManager.executeDirectly(executionContext); nettyExecutorManager.executeDirectly(executionContext);
logger.info("master add kill task :{} id:{} to kill queue", logger.info("master kill taskInstance name :{} taskInstance id:{}",
taskInstance.getName(), taskInstance.getId() ); taskInstance.getName(), taskInstance.getId() );
} }
/**
* whether exists valid worker group
* @param taskInstanceWorkerGroup taskInstanceWorkerGroup
* @return whether exists
*/
public Boolean existsValidWorkerGroup(String taskInstanceWorkerGroup){
Set<String> workerGroups = zookeeperRegistryCenter.getWorkerGroupDirectly();
// not worker group
if (CollectionUtils.isEmpty(workerGroups)){
return false;
}
// has worker group , but not taskInstance assigned worker group
if (!workerGroups.contains(taskInstanceWorkerGroup)){
return false;
}
Set<String> workers = zookeeperRegistryCenter.getWorkerGroupNodesDirectly(taskInstanceWorkerGroup);
if (CollectionUtils.isEmpty(workers)) {
return false;
}
return true;
}
/** /**
* get task timeout parameter * get task timeout parameter
* @return TaskTimeoutParameter * @return TaskTimeoutParameter

2
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java

@ -457,7 +457,7 @@ public class SqlTask extends AbstractTask {
String showTypeName = sqlParameters.getShowType().replace(COMMA,"").trim(); String showTypeName = sqlParameters.getShowType().replace(COMMA,"").trim();
if(EnumUtils.isValidEnum(ShowType.class,showTypeName)){ if(EnumUtils.isValidEnum(ShowType.class,showTypeName)){
Map<String, Object> mailResult = MailUtils.sendMails(receviersList, Map<String, Object> mailResult = MailUtils.sendMails(receviersList,
receviersCcList, title, content, ShowType.valueOf(showTypeName)); receviersCcList, title, content, ShowType.valueOf(showTypeName).getDescp());
if(!(boolean) mailResult.get(STATUS)){ if(!(boolean) mailResult.get(STATUS)){
throw new RuntimeException("send mail failed!"); throw new RuntimeException("send mail failed!");
} }

3
dolphinscheduler-server/src/main/resources/config/install_config.conf

@ -63,7 +63,8 @@ mailPassword="xxxxxxxxxx"
# TLS mail protocol support # TLS mail protocol support
starttlsEnable="false" starttlsEnable="false"
sslTrust="xxxxxxxxxx" #note: sslTrust is the same as mailServerHost
sslTrust="smtp.exmail.qq.com"
# SSL mail protocol support # SSL mail protocol support
# note: The SSL protocol is enabled by default. # note: The SSL protocol is enabled by default.

262
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/consumer/TaskPriorityQueueConsumerTest.java

@ -0,0 +1,262 @@
/*
* 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.server.master.consumer;
import org.apache.dolphinscheduler.common.enums.CommandType;
import org.apache.dolphinscheduler.common.enums.DbType;
import org.apache.dolphinscheduler.common.enums.ExecutionStatus;
import org.apache.dolphinscheduler.common.enums.Priority;
import org.apache.dolphinscheduler.dao.entity.*;
import org.apache.dolphinscheduler.server.master.dispatch.ExecutorDispatcher;
import org.apache.dolphinscheduler.server.master.dispatch.executor.NettyExecutorManager;
import org.apache.dolphinscheduler.server.registry.DependencyConfig;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager;
import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter;
import org.apache.dolphinscheduler.server.zk.SpringZKServer;
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
import org.apache.dolphinscheduler.service.process.ProcessService;
import org.apache.dolphinscheduler.service.queue.TaskPriorityQueue;
import org.apache.dolphinscheduler.service.queue.TaskPriorityQueueImpl;
import org.apache.dolphinscheduler.service.zk.ZookeeperCachedOperator;
import org.apache.dolphinscheduler.service.zk.ZookeeperConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Date;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={DependencyConfig.class, SpringApplicationContext.class, SpringZKServer.class,
NettyExecutorManager.class, ExecutorDispatcher.class, ZookeeperRegistryCenter.class, TaskPriorityQueueConsumer.class,
ZookeeperNodeManager.class, ZookeeperCachedOperator.class, ZookeeperConfig.class})
public class TaskPriorityQueueConsumerTest {
@Autowired
private TaskPriorityQueue taskPriorityQueue;
@Autowired
private TaskPriorityQueueConsumer taskPriorityQueueConsumer;
@Autowired
private ProcessService processService;
@Autowired
private ExecutorDispatcher dispatcher;
@Before
public void init(){
Tenant tenant = new Tenant();
tenant.setId(1);
tenant.setTenantCode("journey");
tenant.setTenantName("journey");
tenant.setDescription("journey");
tenant.setQueueId(1);
tenant.setCreateTime(new Date());
tenant.setUpdateTime(new Date());
Mockito.when(processService.getTenantForProcess(1,2)).thenReturn(tenant);
Mockito.when(processService.queryUserQueueByProcessInstanceId(1)).thenReturn("default");
}
@Test
public void testSHELLTask() throws Exception {
TaskInstance taskInstance = new TaskInstance();
taskInstance.setId(1);
taskInstance.setTaskType("SHELL");
taskInstance.setProcessDefinitionId(1);
taskInstance.setProcessInstanceId(1);
taskInstance.setState(ExecutionStatus.KILL);
taskInstance.setTaskJson("{\"conditionResult\":\"{\\\"successNode\\\":[\\\"\\\"],\\\"failedNode\\\":[\\\"\\\"]}\",\"conditionsTask\":false,\"depList\":[],\"dependence\":\"{}\",\"forbidden\":false,\"id\":\"tasks-55201\",\"maxRetryTimes\":0,\"name\":\"测试任务\",\"params\":\"{\\\"rawScript\\\":\\\"echo \\\\\\\"测试任务\\\\\\\"\\\",\\\"localParams\\\":[],\\\"resourceList\\\":[]}\",\"preTasks\":\"[]\",\"retryInterval\":1,\"runFlag\":\"NORMAL\",\"taskInstancePriority\":\"MEDIUM\",\"taskTimeoutParameter\":{\"enable\":false,\"interval\":0},\"timeout\":\"{\\\"enable\\\":false,\\\"strategy\\\":\\\"\\\"}\",\"type\":\"SHELL\",\"workerGroup\":\"default\"}");
taskInstance.setProcessInstancePriority(Priority.MEDIUM);
taskInstance.setWorkerGroup("default");
taskInstance.setExecutorId(2);
ProcessInstance processInstance = new ProcessInstance();
processInstance.setTenantId(1);
processInstance.setCommandType(CommandType.START_PROCESS);
taskInstance.setProcessInstance(processInstance);
ProcessDefinition processDefinition = new ProcessDefinition();
processDefinition.setUserId(2);
processDefinition.setProjectId(1);
taskInstance.setProcessDefine(processDefinition);
Mockito.when(processService.getTaskInstanceDetailByTaskId(1)).thenReturn(taskInstance);
taskPriorityQueue.put("2_1_2_1_default");
Thread.sleep(10000);
}
@Test
public void testSQLTask() throws Exception {
TaskInstance taskInstance = new TaskInstance();
taskInstance.setId(1);
taskInstance.setTaskType("SQL");
taskInstance.setProcessDefinitionId(1);
taskInstance.setProcessInstanceId(1);
taskInstance.setState(ExecutionStatus.KILL);
taskInstance.setTaskJson("{\"conditionsTask\":false,\"depList\":[],\"dependence\":\"{}\",\"forbidden\":false,\"id\":\"tasks-3655\",\"maxRetryTimes\":0,\"name\":\"UDF测试\",\"params\":\"{\\\"postStatements\\\":[],\\\"connParams\\\":\\\"\\\",\\\"receiversCc\\\":\\\"\\\",\\\"udfs\\\":\\\"1\\\",\\\"type\\\":\\\"HIVE\\\",\\\"title\\\":\\\"test\\\",\\\"sql\\\":\\\"select id,name,ds,zodia(ds) from t_journey_user\\\",\\\"preStatements\\\":[],\\\"sqlType\\\":0,\\\"receivers\\\":\\\"825193156@qq.com\\\",\\\"datasource\\\":3,\\\"showType\\\":\\\"TABLE\\\",\\\"localParams\\\":[]}\",\"preTasks\":\"[]\",\"retryInterval\":1,\"runFlag\":\"NORMAL\",\"taskInstancePriority\":\"MEDIUM\",\"taskTimeoutParameter\":{\"enable\":false,\"interval\":0},\"timeout\":\"{\\\"enable\\\":false,\\\"strategy\\\":\\\"\\\"}\",\"type\":\"SQL\"}");
taskInstance.setProcessInstancePriority(Priority.MEDIUM);
taskInstance.setWorkerGroup("default");
taskInstance.setExecutorId(2);
ProcessInstance processInstance = new ProcessInstance();
processInstance.setTenantId(1);
processInstance.setCommandType(CommandType.START_PROCESS);
taskInstance.setProcessInstance(processInstance);
ProcessDefinition processDefinition = new ProcessDefinition();
processDefinition.setUserId(2);
processDefinition.setProjectId(1);
taskInstance.setProcessDefine(processDefinition);
Mockito.when(processService.getTaskInstanceDetailByTaskId(1)).thenReturn(taskInstance);
taskPriorityQueue.put("2_1_2_1_default");
DataSource dataSource = new DataSource();
dataSource.setId(1);
dataSource.setName("sqlDatasource");
dataSource.setType(DbType.MYSQL);
dataSource.setUserId(2);
dataSource.setConnectionParams("{\"address\":\"jdbc:mysql://192.168.221.185:3306\",\"database\":\"dolphinscheduler_qiaozhanwei\",\"jdbcUrl\":\"jdbc:mysql://192.168.221.185:3306/dolphinscheduler_qiaozhanwei\",\"user\":\"root\",\"password\":\"root@123\"}");
dataSource.setCreateTime(new Date());
dataSource.setUpdateTime(new Date());
Mockito.when(processService.findDataSourceById(1)).thenReturn(dataSource);
Thread.sleep(10000);
}
@Test
public void testDataxTask() throws Exception {
TaskInstance taskInstance = new TaskInstance();
taskInstance.setId(1);
taskInstance.setTaskType("DATAX");
taskInstance.setProcessDefinitionId(1);
taskInstance.setProcessInstanceId(1);
taskInstance.setState(ExecutionStatus.KILL);
taskInstance.setTaskJson("{\"conditionResult\":\"{\\\"successNode\\\":[\\\"\\\"],\\\"failedNode\\\":[\\\"\\\"]}\",\"conditionsTask\":false,\"depList\":[],\"dependence\":\"{}\",\"forbidden\":false,\"id\":\"tasks-97625\",\"maxRetryTimes\":0,\"name\":\"MySQL数据相互导入\",\"params\":\"{\\\"targetTable\\\":\\\"pv2\\\",\\\"postStatements\\\":[],\\\"jobSpeedRecord\\\":1000,\\\"customConfig\\\":0,\\\"dtType\\\":\\\"MYSQL\\\",\\\"dsType\\\":\\\"MYSQL\\\",\\\"jobSpeedByte\\\":0,\\\"dataSource\\\":80,\\\"dataTarget\\\":80,\\\"sql\\\":\\\"SELECT dt,count FROM pv\\\",\\\"preStatements\\\":[]}\",\"preTasks\":\"[]\",\"retryInterval\":1,\"runFlag\":\"NORMAL\",\"taskInstancePriority\":\"MEDIUM\",\"taskTimeoutParameter\":{\"enable\":false,\"interval\":0},\"timeout\":\"{\\\"enable\\\":false,\\\"strategy\\\":\\\"\\\"}\",\"type\":\"DATAX\",\"workerGroup\":\"default\"}");
taskInstance.setProcessInstancePriority(Priority.MEDIUM);
taskInstance.setWorkerGroup("default");
taskInstance.setExecutorId(2);
ProcessInstance processInstance = new ProcessInstance();
processInstance.setTenantId(1);
processInstance.setCommandType(CommandType.START_PROCESS);
taskInstance.setProcessInstance(processInstance);
ProcessDefinition processDefinition = new ProcessDefinition();
processDefinition.setUserId(2);
processDefinition.setProjectId(1);
taskInstance.setProcessDefine(processDefinition);
Mockito.when(processService.getTaskInstanceDetailByTaskId(1)).thenReturn(taskInstance);
taskPriorityQueue.put("2_1_2_1_default");
DataSource dataSource = new DataSource();
dataSource.setId(80);
dataSource.setName("datax");
dataSource.setType(DbType.MYSQL);
dataSource.setUserId(2);
dataSource.setConnectionParams("{\"address\":\"jdbc:mysql://192.168.221.185:3306\",\"database\":\"dolphinscheduler_qiaozhanwei\",\"jdbcUrl\":\"jdbc:mysql://192.168.221.185:3306/dolphinscheduler_qiaozhanwei\",\"user\":\"root\",\"password\":\"root@123\"}");
dataSource.setCreateTime(new Date());
dataSource.setUpdateTime(new Date());
Mockito.when(processService.findDataSourceById(80)).thenReturn(dataSource);
Thread.sleep(10000);
}
@Test
public void testSqoopTask() throws Exception {
TaskInstance taskInstance = new TaskInstance();
taskInstance.setId(1);
taskInstance.setTaskType("SQOOP");
taskInstance.setProcessDefinitionId(1);
taskInstance.setProcessInstanceId(1);
taskInstance.setState(ExecutionStatus.KILL);
taskInstance.setTaskJson("{\"conditionResult\":\"{\\\"successNode\\\":[\\\"\\\"],\\\"failedNode\\\":[\\\"\\\"]}\",\"conditionsTask\":false,\"depList\":[],\"dependence\":\"{}\",\"forbidden\":false,\"id\":\"tasks-63634\",\"maxRetryTimes\":0,\"name\":\"MySQL数据导入HDSF\",\"params\":\"{\\\"sourceType\\\":\\\"MYSQL\\\",\\\"targetType\\\":\\\"HDFS\\\",\\\"targetParams\\\":\\\"{\\\\\\\"targetPath\\\\\\\":\\\\\\\"/test/datatest\\\\\\\",\\\\\\\"deleteTargetDir\\\\\\\":true,\\\\\\\"fileType\\\\\\\":\\\\\\\"--as-textfile\\\\\\\",\\\\\\\"compressionCodec\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"fieldsTerminated\\\\\\\":\\\\\\\",\\\\\\\",\\\\\\\"linesTerminated\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\"}\\\",\\\"modelType\\\":\\\"import\\\",\\\"sourceParams\\\":\\\"{\\\\\\\"srcType\\\\\\\":\\\\\\\"MYSQL\\\\\\\",\\\\\\\"srcDatasource\\\\\\\":1,\\\\\\\"srcTable\\\\\\\":\\\\\\\"t_ds_user\\\\\\\",\\\\\\\"srcQueryType\\\\\\\":\\\\\\\"0\\\\\\\",\\\\\\\"srcQuerySql\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"srcColumnType\\\\\\\":\\\\\\\"0\\\\\\\",\\\\\\\"srcColumns\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"srcConditionList\\\\\\\":[],\\\\\\\"mapColumnHive\\\\\\\":[],\\\\\\\"mapColumnJava\\\\\\\":[]}\\\",\\\"localParams\\\":[],\\\"concurrency\\\":1}\",\"preTasks\":\"[]\",\"retryInterval\":1,\"runFlag\":\"NORMAL\",\"taskInstancePriority\":\"MEDIUM\",\"taskTimeoutParameter\":{\"enable\":false,\"interval\":0},\"timeout\":\"{\\\"enable\\\":false,\\\"strategy\\\":\\\"\\\"}\",\"type\":\"SQOOP\",\"workerGroup\":\"default\"}");
taskInstance.setProcessInstancePriority(Priority.MEDIUM);
taskInstance.setWorkerGroup("default");
taskInstance.setExecutorId(2);
ProcessInstance processInstance = new ProcessInstance();
processInstance.setTenantId(1);
processInstance.setCommandType(CommandType.START_PROCESS);
taskInstance.setProcessInstance(processInstance);
ProcessDefinition processDefinition = new ProcessDefinition();
processDefinition.setUserId(2);
processDefinition.setProjectId(1);
taskInstance.setProcessDefine(processDefinition);
Mockito.when(processService.getTaskInstanceDetailByTaskId(1)).thenReturn(taskInstance);
taskPriorityQueue.put("2_1_2_1_default");
DataSource dataSource = new DataSource();
dataSource.setId(1);
dataSource.setName("datax");
dataSource.setType(DbType.MYSQL);
dataSource.setUserId(2);
dataSource.setConnectionParams("{\"address\":\"jdbc:mysql://192.168.221.185:3306\",\"database\":\"dolphinscheduler_qiaozhanwei\",\"jdbcUrl\":\"jdbc:mysql://192.168.221.185:3306/dolphinscheduler_qiaozhanwei\",\"user\":\"root\",\"password\":\"root@123\"}");
dataSource.setCreateTime(new Date());
dataSource.setUpdateTime(new Date());
Mockito.when(processService.findDataSourceById(1)).thenReturn(dataSource);
Thread.sleep(10000);
}
@Test
public void testTaskInstanceIsFinalState(){
TaskInstance taskInstance = new TaskInstance();
taskInstance.setId(1);
taskInstance.setTaskType("SHELL");
taskInstance.setProcessDefinitionId(1);
taskInstance.setProcessInstanceId(1);
taskInstance.setState(ExecutionStatus.KILL);
taskInstance.setTaskJson("{\"conditionResult\":\"{\\\"successNode\\\":[\\\"\\\"],\\\"failedNode\\\":[\\\"\\\"]}\",\"conditionsTask\":false,\"depList\":[],\"dependence\":\"{}\",\"forbidden\":false,\"id\":\"tasks-55201\",\"maxRetryTimes\":0,\"name\":\"测试任务\",\"params\":\"{\\\"rawScript\\\":\\\"echo \\\\\\\"测试任务\\\\\\\"\\\",\\\"localParams\\\":[],\\\"resourceList\\\":[]}\",\"preTasks\":\"[]\",\"retryInterval\":1,\"runFlag\":\"NORMAL\",\"taskInstancePriority\":\"MEDIUM\",\"taskTimeoutParameter\":{\"enable\":false,\"interval\":0},\"timeout\":\"{\\\"enable\\\":false,\\\"strategy\\\":\\\"\\\"}\",\"type\":\"SHELL\",\"workerGroup\":\"default\"}");
taskInstance.setProcessInstancePriority(Priority.MEDIUM);
taskInstance.setWorkerGroup("default");
taskInstance.setExecutorId(2);
Mockito.when( processService.findTaskInstanceById(1)).thenReturn(taskInstance);
taskPriorityQueueConsumer.taskInstanceIsFinalState(1);
}
}

80
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/runner/MasterTaskExecThreadTest.java

@ -0,0 +1,80 @@
/*
* 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.server.master.runner;
import junit.framework.Assert;
import org.apache.dolphinscheduler.server.master.config.MasterConfig;
import org.apache.dolphinscheduler.server.master.consumer.TaskPriorityQueueConsumer;
import org.apache.dolphinscheduler.server.master.dispatch.ExecutorDispatcher;
import org.apache.dolphinscheduler.server.master.dispatch.executor.NettyExecutorManager;
import org.apache.dolphinscheduler.server.registry.DependencyConfig;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager;
import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter;
import org.apache.dolphinscheduler.server.zk.SpringZKServer;
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
import org.apache.dolphinscheduler.service.queue.TaskPriorityQueueImpl;
import org.apache.dolphinscheduler.service.zk.ZookeeperCachedOperator;
import org.apache.dolphinscheduler.service.zk.ZookeeperConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.HashSet;
import java.util.Set;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={DependencyConfig.class, SpringApplicationContext.class, SpringZKServer.class,
NettyExecutorManager.class, ExecutorDispatcher.class, ZookeeperRegistryCenter.class, TaskPriorityQueueConsumer.class,
ZookeeperNodeManager.class, ZookeeperCachedOperator.class, ZookeeperConfig.class, MasterConfig.class})
public class MasterTaskExecThreadTest {
@Test
public void testExistsValidWorkerGroup1(){
ZookeeperRegistryCenter zookeeperRegistryCenter = Mockito.mock(ZookeeperRegistryCenter.class);
Mockito.when(zookeeperRegistryCenter.getWorkerGroupDirectly()).thenReturn(null);
MasterTaskExecThread masterTaskExecThread = new MasterTaskExecThread(null);
masterTaskExecThread.existsValidWorkerGroup("default");
}
@Test
public void testExistsValidWorkerGroup2(){
ZookeeperRegistryCenter zookeeperRegistryCenter = Mockito.mock(ZookeeperRegistryCenter.class);
Set<String> workerGorups = new HashSet<>();
workerGorups.add("test1");
workerGorups.add("test2");
Mockito.when(zookeeperRegistryCenter.getWorkerGroupDirectly()).thenReturn(workerGorups);
MasterTaskExecThread masterTaskExecThread = new MasterTaskExecThread(null);
masterTaskExecThread.existsValidWorkerGroup("default");
}
@Test
public void testExistsValidWorkerGroup3(){
ZookeeperRegistryCenter zookeeperRegistryCenter = Mockito.mock(ZookeeperRegistryCenter.class);
Set<String> workerGorups = new HashSet<>();
workerGorups.add("test1");
Mockito.when(zookeeperRegistryCenter.getWorkerGroupDirectly()).thenReturn(workerGorups);
Mockito.when(zookeeperRegistryCenter.getWorkerGroupNodesDirectly("test1")).thenReturn(workerGorups);
MasterTaskExecThread masterTaskExecThread = new MasterTaskExecThread(null);
masterTaskExecThread.existsValidWorkerGroup("test1");
}
}

8
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/registry/DependencyConfig.java

@ -20,11 +20,14 @@ package org.apache.dolphinscheduler.server.registry;
import org.apache.dolphinscheduler.dao.AlertDao; import org.apache.dolphinscheduler.dao.AlertDao;
import org.apache.dolphinscheduler.dao.mapper.*; import org.apache.dolphinscheduler.dao.mapper.*;
import org.apache.dolphinscheduler.server.master.cache.impl.TaskInstanceCacheManagerImpl; import org.apache.dolphinscheduler.server.master.cache.impl.TaskInstanceCacheManagerImpl;
import org.apache.dolphinscheduler.server.master.dispatch.ExecutorDispatcher;
import org.apache.dolphinscheduler.server.master.dispatch.host.HostManager; import org.apache.dolphinscheduler.server.master.dispatch.host.HostManager;
import org.apache.dolphinscheduler.server.master.dispatch.host.RandomHostManager; import org.apache.dolphinscheduler.server.master.dispatch.host.RandomHostManager;
import org.apache.dolphinscheduler.server.master.processor.queue.TaskResponseService; import org.apache.dolphinscheduler.server.master.processor.queue.TaskResponseService;
import org.apache.dolphinscheduler.server.worker.processor.TaskCallbackService; import org.apache.dolphinscheduler.server.worker.processor.TaskCallbackService;
import org.apache.dolphinscheduler.service.process.ProcessService; import org.apache.dolphinscheduler.service.process.ProcessService;
import org.apache.dolphinscheduler.service.queue.TaskPriorityQueue;
import org.apache.dolphinscheduler.service.queue.TaskPriorityQueueImpl;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -144,4 +147,9 @@ public class DependencyConfig {
public TaskResponseService taskResponseService(){ public TaskResponseService taskResponseService(){
return Mockito.mock(TaskResponseService.class); return Mockito.mock(TaskResponseService.class);
} }
@Bean
public TaskPriorityQueue taskPriorityQueue(){
return new TaskPriorityQueueImpl();
}
} }

2
dolphinscheduler-ui/package.json

@ -55,7 +55,7 @@
"html-loader": "^0.5.5", "html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.8.2", "mini-css-extract-plugin": "^0.8.2",
"node-sass": "^4.13.1", "node-sass": "^4.14.0",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"progress-bar-webpack-plugin": "^1.12.1", "progress-bar-webpack-plugin": "^1.12.1",
"rimraf": "^2.6.2", "rimraf": "^2.6.2",

7
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue

@ -259,8 +259,15 @@
if (v2.name === v1.name) { if (v2.name === v1.name) {
let dom = $(`#${v2.id}`) let dom = $(`#${v2.id}`)
let state = dom.find('.state-p') let state = dom.find('.state-p')
let depState = ''
taskList.forEach(item=>{
if(item.name==v1.name) {
depState = item.state
}
})
dom.attr('data-state-id', v1.stateId) dom.attr('data-state-id', v1.stateId)
dom.attr('data-dependent-result', v1.dependentResult || '') dom.attr('data-dependent-result', v1.dependentResult || '')
dom.attr('data-dependent-depState', depState)
state.append(`<strong class="${v1.icoUnicode} ${v1.isSpin ? 'as as-spin' : ''}" style="color:${v1.color}" data-toggle="tooltip" data-html="true" data-container="body"></strong>`) state.append(`<strong class="${v1.icoUnicode} ${v1.isSpin ? 'as as-spin' : ''}" style="color:${v1.color}" data-toggle="tooltip" data-html="true" data-container="body"></strong>`)
state.find('strong').attr('title', titleTpl(v2, v1.desc)) state.find('strong').attr('title', titleTpl(v2, v1.desc))
} }

7
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/_source/nodeStatus.vue

@ -28,8 +28,8 @@
<template v-if="isInstance"> <template v-if="isInstance">
<span class="instance-state"> <span class="instance-state">
<em class="iconfont ans-icon-success-solid" :class="'icon-' + el.state" v-if="el.state === 'SUCCESS'" data-toggle="tooltip" data-container="body" :title="$t('success')"></em> <em class="iconfont ans-icon-success-solid" :class="'icon-' + el.state" v-if="el.state === 'SUCCESS'" data-toggle="tooltip" data-container="body" :title="$t('success')"></em>
<em class="iconfont ans-icon-clock" :class="'icon-' + el.state" v-if="el.state === 'WAITING'" data-toggle="tooltip" data-container="body" :title="$t('waiting')"></em> <em class="iconfont ans-icon-clock" :class="'icon-' + el.state" v-if="el.state === 'RUNNING_EXEUTION'" data-toggle="tooltip" data-container="body" :title="$t('waiting')"></em>
<em class="iconfont ans-icon-fail-solid" :class="'icon-' + el.state" v-if="el.state === 'FAILED'" data-toggle="tooltip" data-container="body" :title="$t('failed')"></em> <em class="iconfont ans-icon-fail-solid" :class="'icon-' + el.state" v-if="el.state === 'FAILURE'" data-toggle="tooltip" data-container="body" :title="$t('failed')"></em>
</span> </span>
</template> </template>
<span class="operation"> <span class="operation">
@ -176,8 +176,7 @@
} }
}) })
}, },
mounted () { mounted () {},
},
components: {} components: {}
} }
</script> </script>

9
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/conditions.vue

@ -143,13 +143,20 @@
created () { created () {
let o = this.backfillItem let o = this.backfillItem
let dependentResult = $(`#${o.id}`).data('dependent-result') || {} let dependentResult = $(`#${o.id}`).data('dependent-result') || {}
// Does not represent an empty object backfill // Does not represent an empty object backfill
if (!_.isEmpty(o)) { if (!_.isEmpty(o)) {
this.relation = _.cloneDeep(o.dependence.relation) || 'AND' this.relation = _.cloneDeep(o.dependence.relation) || 'AND'
this.dependTaskList = _.cloneDeep(o.dependence.dependTaskList) || [] this.dependTaskList = _.cloneDeep(o.dependence.dependTaskList) || []
let defaultState = this.isDetails ? 'WAITING' : '' let defaultState = this.isDetails ? 'WAITING' : ''
// Process instance return status display matches by key // Process instance return status display matches by key
_.map(this.dependTaskList, v => _.map(v.dependItemList, v1 => v1.state = dependentResult[`${v1.definitionId}-${v1.depTasks}-${v1.cycle}-${v1.dateValue}`] || defaultState)) _.map(this.dependTaskList, v => _.map(v.dependItemList, v1 => {
$(`#${o.id}`).siblings().each(function(){
if(v1.depTasks == $(this).text()) {
v1.state = $(this).attr('data-dependent-depstate')
}
});
}))
} }
}, },
mounted () { mounted () {

24
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue

@ -19,34 +19,36 @@
<div class="table-box"> <div class="table-box">
<table class="fixed"> <table class="fixed">
<tr> <tr>
<th scope="col" width="50"> <th scope="col" style="min-width: 50px">
<x-checkbox @on-change="_topCheckBoxClick" v-model="checkAll"></x-checkbox> <x-checkbox @on-change="_topCheckBoxClick" v-model="checkAll"></x-checkbox>
</th> </th>
<th scope="col" width="40"> <th scope="col" style="min-width: 40px">
<span>{{$t('#')}}</span> <span>{{$t('#')}}</span>
</th> </th>
<th scope="col"> <th scope="col" style="min-width: 200px">
<span>{{$t('Process Name')}}</span> <span>{{$t('Process Name')}}</span>
</th> </th>
<th scope="col" width="50"> <th scope="col" style="min-width: 50px">
<span>{{$t('State')}}</span> <span>{{$t('State')}}</span>
</th> </th>
<th scope="col" width="130"> <th scope="col" style="min-width: 130px">
<span>{{$t('Create Time')}}</span> <span>{{$t('Create Time')}}</span>
</th> </th>
<th scope="col" width="130"> <th scope="col" style="min-width: 130px">
<span>{{$t('Update Time')}}</span> <span>{{$t('Update Time')}}</span>
</th> </th>
<th scope="col"> <th scope="col" style="min-width: 150px">
<span>{{$t('Description')}}</span> <span>{{$t('Description')}}</span>
</th> </th>
<th scope="col" width="130"> <th scope="col" style="min-width: 70px">
<span>{{$t('Modify User')}}</span> <span>{{$t('Modify User')}}</span>
</th> </th>
<th scope="col" width="90"> <th scope="col" style="min-width: 70px">
<span>{{$t('Timing state')}}</span> <div style="width: 80px">
<span>{{$t('Timing state')}}</span>
</div>
</th> </th>
<th scope="col" width="300"> <th scope="col" style="min-width: 300px">
<span>{{$t('Operation')}}</span> <span>{{$t('Operation')}}</span>
</th> </th>
</tr> </tr>

81
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/index.vue

@ -15,29 +15,30 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-list-construction :title="$t('Process definition')"> <div class="wrap-definition">
<template slot="conditions"> <m-list-construction :title="$t('Process definition')">
<m-conditions @on-conditions="_onConditions"> <template slot="conditions">
<template slot="button-group"> <m-conditions @on-conditions="_onConditions">
<x-button type="ghost" size="small" @click="() => this.$router.push({name: 'definition-create'})">{{$t('Create process')}}</x-button> <template slot="button-group">
<x-button type="ghost" size="small" @click="_uploading">{{$t('Import process')}}</x-button> <x-button type="ghost" size="small" @click="() => this.$router.push({name: 'definition-create'})">{{$t('Create process')}}</x-button>
<x-button type="ghost" size="small" @click="_uploading">{{$t('Import process')}}</x-button>
</template> </template>
</m-conditions> </m-conditions>
</template>
<template slot="content">
<template v-if="processListP.length || total>0">
<m-list :process-list="processListP" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page" show-sizer :page-size-options="[10,30,50]" @on-size-change="_pageSize"></x-page>
</div>
</template> </template>
<template v-if="!processListP.length && total<=0"> <template slot="content">
<m-no-data></m-no-data> <template v-if="processListP.length || total>0">
<m-list :process-list="processListP" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page" show-sizer :page-size-options="[10,30,50]" @on-size-change="_pageSize"></x-page>
</div>
</template>
<template v-if="!processListP.length && total<=0">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</template> </template>
<m-spin :is-spin="isLoading"></m-spin> </m-list-construction>
</template> </div>
</m-list-construction>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
@ -64,7 +65,8 @@
pageNo: 1, pageNo: 1,
searchVal: '', searchVal: '',
userId: '' userId: ''
} },
isLeft: true
} }
}, },
mixins: [listUrlParamHandle], mixins: [listUrlParamHandle],
@ -98,6 +100,11 @@
* get data list * get data list
*/ */
_getList (flag) { _getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag this.isLoading = !flag
this.getProcessListP(this.searchParams).then(res => { this.getProcessListP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) { if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
@ -133,7 +140,37 @@
mounted() { mounted() {
this.$modal.destroy() this.$modal.destroy()
}, },
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mList, mConditions, mSpin, mListConstruction, mSecondaryMenu, mNoData } components: { mList, mConditions, mSpin, mListConstruction, mSecondaryMenu, mNoData }
} }
</script> </script>
<style lang="scss" rel="stylesheet/scss">
.wrap-definition {
.table-box {
overflow-y: scroll;
}
.table-box {
.fixed {
table-layout: auto;
tr {
th:last-child,td:last-child {
background: inherit;
width: 300px;
height: 40px;
line-height: 40px;
border-left:1px solid #ecf3ff;
position: absolute;
right: 0;
z-index: 2;
}
th:nth-last-child(2) {
padding-right: 330px;
}
}
}
}
}
</style>

47
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue

@ -19,46 +19,48 @@
<div class="table-box"> <div class="table-box">
<table class="fixed"> <table class="fixed">
<tr> <tr>
<th scope="col" width="50"> <th scope="col" style="min-width: 50px">
<x-checkbox @on-change="_topCheckBoxClick" v-model="checkAll"></x-checkbox> <x-checkbox @on-change="_topCheckBoxClick" v-model="checkAll"></x-checkbox>
</th> </th>
<th scope="col" width="30"> <th scope="col" style="min-width: 30px">
<span>{{$t('#')}}</span> <span>{{$t('#')}}</span>
</th> </th>
<th scope="col" width="70"> <th scope="col" style="min-width: 300px">
<span>{{$t('Process Name')}}</span> <span>{{$t('Process Name')}}</span>
</th> </th>
<th scope="col" width="60"> <th scope="col" style="min-width: 30px">
<span>{{$t('Executor')}}</span> <span>{{$t('State')}}</span>
</th> </th>
<th scope="col" width="70"> <th scope="col" style="min-width: 70px">
<span>{{$t('Run Type')}}</span> <span>{{$t('Run Type')}}</span>
</th> </th>
<th scope="col" width="130"> <th scope="col" style="min-width: 130px">
<span>{{$t('Scheduling Time')}}</span> <span>{{$t('Scheduling Time')}}</span>
</th> </th>
<th scope="col" width="130"> <th scope="col" style="min-width: 130px">
<span>{{$t('Start Time')}}</span> <span>{{$t('Start Time')}}</span>
</th> </th>
<th scope="col" width="130"> <th scope="col" style="min-width: 130px">
<span>{{$t('End Time')}}</span> <span>{{$t('End Time')}}</span>
</th> </th>
<th scope="col" width="60"> <th scope="col" style="min-width: 60px">
<span>{{$t('Duration')}}s</span> <span>{{$t('Duration')}}s</span>
</th> </th>
<th scope="col" width="60"> <th scope="col" style="min-width: 60px">
<span>{{$t('Run Times')}}</span> <span>{{$t('Run Times')}}</span>
</th> </th>
<th scope="col" width="125"> <th scope="col" style="min-width: 55px">
<span>{{$t('host')}}</span>
</th>
<th scope="col" width="55">
<span>{{$t('fault-tolerant sign')}}</span> <span>{{$t('fault-tolerant sign')}}</span>
</th> </th>
<th scope="col" width="30"> <th scope="col" style="min-width: 135px">
<span>{{$t('State')}}</span> <span>{{$t('host')}}</span>
</th>
<th scope="col" style="min-width: 60px">
<div style="width: 60px">
<span>{{$t('Executor')}}</span>
</div>
</th> </th>
<th scope="col" width="210"> <th scope="col" style="min-width: 210px">
<span>{{$t('Operation')}}</span> <span>{{$t('Operation')}}</span>
</th> </th>
</tr> </tr>
@ -71,8 +73,7 @@
<span class="ellipsis" style="padding-left: 4px;"><router-link :to="{ path: '/projects/instance/list/' + item.id}" tag="a" class="links" :title="item.name">{{item.name}}</router-link></span> <span class="ellipsis" style="padding-left: 4px;"><router-link :to="{ path: '/projects/instance/list/' + item.id}" tag="a" class="links" :title="item.name">{{item.name}}</router-link></span>
</td> </td>
<td> <td>
<span style="word-break: break-all" v-if="item.executorName">{{item.executorName}}</span> <span v-html="_rtState(item.state)" style="cursor: pointer;"></span>
<span v-else>-</span>
</td> </td>
<td><span>{{_rtRunningType(item.commandType)}}</span></td> <td><span>{{_rtRunningType(item.commandType)}}</span></td>
<td> <td>
@ -89,14 +90,14 @@
</td> </td>
<td width="70"><span>{{item.duration || '-'}}</span></td> <td width="70"><span>{{item.duration || '-'}}</span></td>
<td width="70"><span>{{item.runTimes}}</span></td> <td width="70"><span>{{item.runTimes}}</span></td>
<td><span>{{item.recovery}}</span></td>
<td> <td>
<span v-if="item.host">{{item.host}}</span> <span v-if="item.host">{{item.host}}</span>
<span v-else>-</span> <span v-else>-</span>
</td> </td>
<td><span>{{item.recovery}}</span></td>
<td> <td>
<span v-html="_rtState(item.state)" style="cursor: pointer;"></span> <span style="word-break: break-all" v-if="item.executorName">{{item.executorName}}</span>
<span v-else>-</span>
</td> </td>
<td> <td>
<div v-show="item.disabled"> <div v-show="item.disabled">

68
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/index.vue

@ -15,24 +15,26 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-list-construction :title="$t('Process Instance')"> <div class="wrap-table">
<template slot="conditions"> <m-list-construction :title="$t('Process Instance')">
<m-instance-conditions @on-query="_onQuery"></m-instance-conditions> <template slot="conditions">
</template> <m-instance-conditions @on-query="_onQuery"></m-instance-conditions>
<template slot="content">
<template v-if="processInstanceList.length || total>0">
<m-list :process-instance-list="processInstanceList" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page" show-sizer :page-size-options="[10,30,50]" @on-size-change="_pageSize"></x-page>
</div>
</template> </template>
<template v-if="!processInstanceList.length && total<=0"> <template slot="content">
<m-no-data></m-no-data> <template v-if="processInstanceList.length || total>0">
<m-list :process-instance-list="processInstanceList" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page" show-sizer :page-size-options="[10,30,50]" @on-size-change="_pageSize"></x-page>
</div>
</template>
<template v-if="!processInstanceList.length && total<=0">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</template> </template>
<m-spin :is-spin="isLoading"></m-spin> </m-list-construction>
</template> </div>
</m-list-construction>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
@ -74,7 +76,8 @@
endDate: '', endDate: '',
// Exectuor Name // Exectuor Name
executorName: '' executorName: ''
} },
isLeft: true
} }
}, },
props: {}, props: {},
@ -136,6 +139,11 @@
* @desc Prevent functions from being called multiple times * @desc Prevent functions from being called multiple times
*/ */
_debounceGET: _.debounce(function (flag) { _debounceGET: _.debounce(function (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this._getProcessInstanceListP(flag) this._getProcessInstanceListP(flag)
}, 100, { }, 100, {
'leading': false, 'leading': false,
@ -183,10 +191,36 @@
beforeDestroy () { beforeDestroy () {
// Destruction wheel // Destruction wheel
clearInterval(this.setIntervalP) clearInterval(this.setIntervalP)
sessionStorage.setItem('isLeft',1)
}, },
components: { mList, mInstanceConditions, mSpin, mListConstruction, mSecondaryMenu, mNoData } components: { mList, mInstanceConditions, mSpin, mListConstruction, mSecondaryMenu, mNoData }
} }
</script> </script>
<style lang="scss" rel="stylesheet/scss"> <style lang="scss" rel="stylesheet/scss">
.wrap-table {
.table-box {
overflow-y: scroll;
}
.table-box {
.fixed {
table-layout: auto;
tr {
th:last-child,td:last-child {
background: inherit;
width: 230px;
height: 40px;
line-height: 40px;
border-left:1px solid #ecf3ff;
position: absolute;
right: 0;
z-index: 2;
}
th:nth-last-child(2) {
padding-right: 260px;
}
}
}
}
}
</style> </style>

30
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/_source/list.vue

@ -19,43 +19,45 @@
<div class="table-box"> <div class="table-box">
<table class="fixed"> <table class="fixed">
<tr> <tr>
<th scope="col"> <th scope="col" style="min-width: 50px">
<span>{{$t('#')}}</span> <span>{{$t('#')}}</span>
</th> </th>
<th scope="col"> <th scope="col" style="min-width: 250px">
<span>{{$t('Name')}}</span> <span>{{$t('Name')}}</span>
</th> </th>
<th scope="col"> <th scope="col" style="min-width: 250px">
<span>{{$t('Process Instance')}}</span> <span>{{$t('Process Instance')}}</span>
</th> </th>
<th scope="col" width="70"> <th scope="col" style="min-width: 60px">
<span>{{$t('Executor')}}</span> <span>{{$t('Executor')}}</span>
</th> </th>
<th scope="col" width="90"> <th scope="col" style="min-width: 70px">
<span>{{$t('Node Type')}}</span> <span>{{$t('Node Type')}}</span>
</th> </th>
<th scope="col" width="40"> <th scope="col" style="min-width: 30px">
<span>{{$t('State')}}</span> <span>{{$t('State')}}</span>
</th> </th>
<th scope="col" width="140"> <th scope="col" style="min-width: 130px">
<span>{{$t('Submit Time')}}</span> <span>{{$t('Submit Time')}}</span>
</th> </th>
<th scope="col" width="140"> <th scope="col" style="min-width: 130px">
<span>{{$t('Start Time')}}</span> <span>{{$t('Start Time')}}</span>
</th> </th>
<th scope="col" width="125"> <th scope="col" style="min-width: 130px">
<span>{{$t('End Time')}}</span> <span>{{$t('End Time')}}</span>
</th> </th>
<th scope="col" width="130"> <th scope="col" style="min-width: 130px">
<span>{{$t('host')}}</span> <span>{{$t('host')}}</span>
</th> </th>
<th scope="col" width="70"> <th scope="col" style="min-width: 70px">
<span>{{$t('Duration')}}(s)</span> <span>{{$t('Duration')}}(s)</span>
</th> </th>
<th scope="col" width="84"> <th scope="col" style="min-width: 60px">
<span>{{$t('Retry Count')}}</span> <div style="width: 50px">
<span>{{$t('Retry Count')}}</span>
</div>
</th> </th>
<th scope="col" width="50"> <th scope="col" style="min-width: 50px">
<span>{{$t('Operation')}}</span> <span>{{$t('Operation')}}</span>
</th> </th>
</tr> </tr>

71
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/index.vue

@ -15,24 +15,26 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-list-construction :title="$t('Task Instance')"> <div class="wrap-taskInstance">
<template slot="conditions"> <m-list-construction :title="$t('Task Instance')">
<m-instance-conditions @on-query="_onQuery"></m-instance-conditions> <template slot="conditions">
</template> <m-instance-conditions @on-query="_onQuery"></m-instance-conditions>
<template slot="content">
<template v-if="taskInstanceList.length">
<m-list :task-instance-list="taskInstanceList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page" show-sizer :page-size-options="[10,30,50]" @on-size-change="_pageSize"></x-page>
</div>
</template> </template>
<template v-if="!taskInstanceList.length"> <template slot="content">
<m-no-data></m-no-data> <template v-if="taskInstanceList.length">
<m-list :task-instance-list="taskInstanceList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page" show-sizer :page-size-options="[10,30,50]" @on-size-change="_pageSize"></x-page>
</div>
</template>
<template v-if="!taskInstanceList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</template> </template>
<m-spin :is-spin="isLoading"></m-spin> </m-list-construction>
</template> </div>
</m-list-construction>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
@ -71,7 +73,8 @@
endDate: '', endDate: '',
// Exectuor Name // Exectuor Name
executorName: '' executorName: ''
} },
isLeft: true
} }
}, },
mixins: [listUrlParamHandle], mixins: [listUrlParamHandle],
@ -118,6 +121,11 @@
* @desc Prevent functions from being called multiple times * @desc Prevent functions from being called multiple times
*/ */
_debounceGET: _.debounce(function (flag) { _debounceGET: _.debounce(function (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this._getList(flag) this._getList(flag)
}, 100, { }, 100, {
'leading': false, 'leading': false,
@ -146,7 +154,36 @@
beforeDestroy () { beforeDestroy () {
// Destruction wheel // Destruction wheel
clearInterval(this.setIntervalP) clearInterval(this.setIntervalP)
sessionStorage.setItem('isLeft',1)
}, },
components: { mList, mInstanceConditions, mSpin, mListConstruction, mSecondaryMenu, mNoData } components: { mList, mInstanceConditions, mSpin, mListConstruction, mSecondaryMenu, mNoData }
} }
</script> </script>
<style lang="scss" rel="stylesheet/scss">
.wrap-taskInstance {
.table-box {
overflow-y: scroll;
}
.table-box {
.fixed {
table-layout: auto;
tr {
th:last-child,td:last-child {
background: inherit;
width: 50px;
height: 40px;
line-height: 40px;
border-left:1px solid #ecf3ff;
position: absolute;
right: 0;
z-index: 2;
}
th:nth-last-child(2) {
padding-right: 80px;
}
}
}
}
}
</style>

13
dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/list/index.vue

@ -38,7 +38,7 @@
<template v-if="!fileResourcesList.length && total<=0"> <template v-if="!fileResourcesList.length && total<=0">
<m-no-data></m-no-data> <m-no-data></m-no-data>
</template> </template>
<m-spin :is-spin="isLoading"> <m-spin :is-spin="isLoading" :is-left="isLeft">
</m-spin> </m-spin>
</template> </template>
</m-list-construction> </m-list-construction>
@ -67,7 +67,8 @@
pageNo: 1, pageNo: 1,
searchVal: '', searchVal: '',
type: 'FILE' type: 'FILE'
} },
isLeft: true
} }
}, },
mixins: [listUrlParamHandle], mixins: [listUrlParamHandle],
@ -91,6 +92,11 @@
this.searchParams.pageSize = val this.searchParams.pageSize = val
}, },
_getList (flag) { _getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag this.isLoading = !flag
this.getResourcesListP(this.searchParams).then(res => { this.getResourcesListP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) { if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
@ -125,6 +131,9 @@
mounted () { mounted () {
this.$modal.destroy() this.$modal.destroy()
}, },
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mListConstruction, mConditions, mList, mSpin, mNoData } components: { mListConstruction, mConditions, mList, mSpin, mNoData }
} }
</script> </script>

11
dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/subdirectory/index.vue

@ -42,7 +42,7 @@
<template v-if="!fileResourcesList.length && total<=0"> <template v-if="!fileResourcesList.length && total<=0">
<m-no-data></m-no-data> <m-no-data></m-no-data>
</template> </template>
<m-spin :is-spin="isLoading"> <m-spin :is-spin="isLoading" :is-left="isLeft">
</m-spin> </m-spin>
</div> </div>
</div> </div>
@ -73,6 +73,7 @@
searchVal: '', searchVal: '',
type: 'FILE' type: 'FILE'
}, },
isLeft: true,
breadList: [] breadList: []
} }
}, },
@ -97,6 +98,11 @@
this.searchParams.pageSize = val this.searchParams.pageSize = val
}, },
_getList (flag) { _getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag this.isLoading = !flag
this.getResourcesListP(this.searchParams).then(res => { this.getResourcesListP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) { if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
@ -159,6 +165,9 @@
this.breadList = dir this.breadList = dir
this.$modal.destroy() this.$modal.destroy()
}, },
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mListConstruction, mConditions, mList, mSpin, mNoData } components: { mListConstruction, mConditions, mList, mSpin, mNoData }
} }
</script> </script>

14
dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/function/index.vue

@ -36,8 +36,7 @@
<template v-if="!udfFuncList.length && total<=0"> <template v-if="!udfFuncList.length && total<=0">
<m-no-data></m-no-data> <m-no-data></m-no-data>
</template> </template>
<m-spin :is-spin="isLoading"> <m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</m-spin>
</template> </template>
</m-list-construction> </m-list-construction>
</template> </template>
@ -64,7 +63,8 @@
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
searchVal: '' searchVal: ''
} },
isLeft: true
} }
}, },
mixins: [listUrlParamHandle], mixins: [listUrlParamHandle],
@ -110,6 +110,11 @@
this._debounceGET() this._debounceGET()
}, },
_getList (flag) { _getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag this.isLoading = !flag
this.getUdfFuncListP(this.searchParams).then(res => { this.getUdfFuncListP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) { if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
@ -137,6 +142,9 @@
mounted () { mounted () {
this.$modal.destroy() this.$modal.destroy()
}, },
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mListConstruction, mConditions, mList, mSpin, mCreateUdf, mNoData } components: { mListConstruction, mConditions, mList, mSpin, mCreateUdf, mNoData }
} }
</script> </script>

14
dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/resource/index.vue

@ -37,8 +37,7 @@
<template v-if="!udfResourcesList.length && total<=0"> <template v-if="!udfResourcesList.length && total<=0">
<m-no-data></m-no-data> <m-no-data></m-no-data>
</template> </template>
<m-spin :is-spin="isLoading"> <m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</m-spin>
</template> </template>
</m-list-construction> </m-list-construction>
</template> </template>
@ -66,7 +65,8 @@
pageNo: 1, pageNo: 1,
searchVal: '', searchVal: '',
type: 'UDF' type: 'UDF'
} },
isLeft: true
} }
}, },
mixins: [listUrlParamHandle], mixins: [listUrlParamHandle],
@ -98,6 +98,11 @@
this._debounceGET() this._debounceGET()
}, },
_getList (flag) { _getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag this.isLoading = !flag
this.getResourcesListP(this.searchParams).then(res => { this.getResourcesListP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) { if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
@ -125,6 +130,9 @@
mounted () { mounted () {
this.$modal.destroy() this.$modal.destroy()
}, },
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mListConstruction, mConditions, mList, mSpin, mNoData } components: { mListConstruction, mConditions, mList, mSpin, mNoData }
} }
</script> </script>

11
dolphinscheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/subUdfDirectory/index.vue

@ -41,7 +41,7 @@
<template v-if="!udfResourcesList.length && total<=0"> <template v-if="!udfResourcesList.length && total<=0">
<m-no-data></m-no-data> <m-no-data></m-no-data>
</template> </template>
<m-spin :is-spin="isLoading"> <m-spin :is-spin="isLoading" :is-left="isLeft">
</m-spin> </m-spin>
</div> </div>
</div> </div>
@ -72,6 +72,7 @@
searchVal: '', searchVal: '',
type: 'UDF' type: 'UDF'
}, },
isLeft: true,
breadList: [] breadList: []
} }
}, },
@ -106,6 +107,11 @@
this._debounceGET() this._debounceGET()
}, },
_getList (flag) { _getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag this.isLoading = !flag
this.getResourcesListP(this.searchParams).then(res => { this.getResourcesListP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) { if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
@ -160,6 +166,9 @@
this.breadList = dir this.breadList = dir
this.$modal.destroy() this.$modal.destroy()
}, },
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mListConstruction, mConditions, mList, mSpin, mNoData } components: { mListConstruction, mConditions, mList, mSpin, mNoData }
} }
</script> </script>

11
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/queue/index.vue

@ -38,7 +38,7 @@
<template v-if="!queueList.length && total<=0"> <template v-if="!queueList.length && total<=0">
<m-no-data></m-no-data> <m-no-data></m-no-data>
</template> </template>
<m-spin :is-spin="isLoading"></m-spin> <m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</template> </template>
</m-list-construction> </m-list-construction>
</template> </template>
@ -66,6 +66,7 @@
pageNo: 1, pageNo: 1,
searchVal: '' searchVal: ''
}, },
isLeft: true,
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER' isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER'
} }
}, },
@ -116,6 +117,11 @@
}) })
}, },
_getList (flag) { _getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag this.isLoading = !flag
this.getQueueListP(this.searchParams).then(res => { this.getQueueListP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) { if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
@ -143,6 +149,9 @@
mounted () { mounted () {
this.$modal.destroy() this.$modal.destroy()
}, },
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mList, mListConstruction, mConditions, mSpin, mNoData } components: { mList, mListConstruction, mConditions, mSpin, mNoData }
} }
</script> </script>

11
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/tenement/index.vue

@ -39,7 +39,7 @@
<template v-if="!tenementList.length && total<=0"> <template v-if="!tenementList.length && total<=0">
<m-no-data></m-no-data> <m-no-data></m-no-data>
</template> </template>
<m-spin :is-spin="isLoading"></m-spin> <m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</template> </template>
</m-list-construction> </m-list-construction>
</template> </template>
@ -67,6 +67,7 @@
pageNo: 1, pageNo: 1,
searchVal: '' searchVal: ''
}, },
isLeft: true,
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER' isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER'
} }
}, },
@ -120,6 +121,11 @@
}) })
}, },
_getList (flag) { _getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag this.isLoading = !flag
this.getTenantListP(this.searchParams).then(res => { this.getTenantListP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) { if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
@ -147,6 +153,9 @@
mounted () { mounted () {
this.$modal.destroy() this.$modal.destroy()
}, },
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mList, mListConstruction, mConditions, mSpin, mNoData } components: { mList, mListConstruction, mConditions, mSpin, mNoData }
} }
</script> </script>

2
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue

@ -37,7 +37,7 @@
<template slot="name"><strong>*</strong>{{$t('Password')}}</template> <template slot="name"><strong>*</strong>{{$t('Password')}}</template>
<template slot="content"> <template slot="content">
<x-input <x-input
type="input" type="password"
v-model="userPassword" v-model="userPassword"
:placeholder="$t('Please enter your password')"> :placeholder="$t('Please enter your password')">
</x-input> </x-input>

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

Loading…
Cancel
Save