未验证 提交 0c8d08cb 编写于 作者: K Kirs 提交者: GitHub

[Feature-#3049] Alert Plugin Design(merge alert_plugin_design to dev) (#4495)

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature][ui]Alert plugin design (#3734)

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [Feature-3682][ui]Add form-create plug-in and alarm group management add sample demo (#3683)

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature][ui] Add alarm instance page

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [Feature-3189][alert,spi,dao,plugin-api] base code of dolphinscheduler spi and alert plugin implement (#3601)

* DS SPI

* Add DolphinScheduler SPI , and rebuilt the code of the Alert plug-in based on SPI

* Add DolphinScheduler SPI , and rebuilt the code of the Alert plug-in based on SPI

* add TODO

* delete

* compile

* spi commit

* Plugin Alert

* fix some bug

* add todo

* change web ui from alpacajs to form-create

* remove module

* add plugin schema

* add license header

* update alert and spi module version

* update the alert plugin sub module version

* comment the maven.local.repository param

* move utils from spi to common module

* add license header

* add license header and delete some chinese comment

* update spi packages

* delete no use alert_xx.properties

* update mysql.connector.version back to 5.1.34

* delete no use comment in pom.xml

* update email stmp password

* add license

* add semicolon to sql/upgrade/1.4.0_schema/mysql/dolphinscheduler_ddl.sql file

* format the code style

* format new clase file with checkstyle

* update plugin params to Builder model

* move JSONUtils to SPI because plugin can not dependency common module

* move JSONUtils to SPI because plugin can not dependency common module

* delete collection dependency

* replace PluginParamsTransfer to spi PluginParamsTransfer

* update dolphinscheduler-maven-plugin to 1.0.0

* update license

* update apache-rat-plugin add exclude '.iml' file

* check license

* ArtifactResolver only use in development and configPlugins is not empty

* ArtifactResolver only use in development and configPlugins is not empty

* ArtifactResolver only use in development and configPlugins is not empty

* default datasource should be postgresql

* add license files

* add license files

* postgresql port should be 5432

* postgresql test

* mv show_type to spi

add license header to AlertConstants

* check style fix

* copy check style file from branch dev

* alert show_type set by plugin

* alert show_type set by plugin

* add PluginDefineMapper to dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/registry/DependencyConfig.java

* add Bean to TaskCallbackServiceTestConfig

* add Bean to TaskCallbackServiceTestConfig

* fix check style

* check style fix

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* fix check style

* [Feature-3682][ui]Add form-create plug-in and alarm group management add sample demo (#3683)

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* check style fix

* rollback test change

* rollback test change

* rollback dao pom change

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* add ut to pom.xml

* add upgrade schema to global schema

* fix ut failed

* fix ut failed

* fix ut failed

* fix ut failed

* add test EmailAlertPluginTest to pom.xml

* fix ut failed

* fix ut failed

* fix check style

* update license header to presto license header

* presto license header not check

* fix ut coverage

* fix ut coverage

* fix ut

* fix ut

* fix ut

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage
Co-authored-by: Nbreak60 <790061044@qq.com>

* Replace the tenant management page ui with element-ui (#3891)

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [Feature-3682][ui]Add form-create plug-in and alarm group management add sample demo (#3683)

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature][ui] Add alarm instance page

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature][ui]Alert plugin design (#3734)

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [Feature-3682][ui]Add form-create plug-in and alarm group management add sample demo (#3683)

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature][ui] Add alarm instance page

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [Feature-3189][alert,spi,dao,plugin-api] base code of dolphinscheduler spi and alert plugin implement (#3601)

* DS SPI

* Add DolphinScheduler SPI , and rebuilt the code of the Alert plug-in based on SPI

* Add DolphinScheduler SPI , and rebuilt the code of the Alert plug-in based on SPI

* add TODO

* delete

* compile

* spi commit

* Plugin Alert

* fix some bug

* add todo

* change web ui from alpacajs to form-create

* remove module

* add plugin schema

* add license header

* update alert and spi module version

* update the alert plugin sub module version

* comment the maven.local.repository param

* move utils from spi to common module

* add license header

* add license header and delete some chinese comment

* update spi packages

* delete no use alert_xx.properties

* update mysql.connector.version back to 5.1.34

* delete no use comment in pom.xml

* update email stmp password

* add license

* add semicolon to sql/upgrade/1.4.0_schema/mysql/dolphinscheduler_ddl.sql file

* format the code style

* format new clase file with checkstyle

* update plugin params to Builder model

* move JSONUtils to SPI because plugin can not dependency common module

* move JSONUtils to SPI because plugin can not dependency common module

* delete collection dependency

* replace PluginParamsTransfer to spi PluginParamsTransfer

* update dolphinscheduler-maven-plugin to 1.0.0

* update license

* update apache-rat-plugin add exclude '.iml' file

* check license

* ArtifactResolver only use in development and configPlugins is not empty

* ArtifactResolver only use in development and configPlugins is not empty

* ArtifactResolver only use in development and configPlugins is not empty

* default datasource should be postgresql

* add license files

* add license files

* postgresql port should be 5432

* postgresql test

* mv show_type to spi

add license header to AlertConstants

* check style fix

* copy check style file from branch dev

* alert show_type set by plugin

* alert show_type set by plugin

* add PluginDefineMapper to dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/registry/DependencyConfig.java

* add Bean to TaskCallbackServiceTestConfig

* add Bean to TaskCallbackServiceTestConfig

* fix check style

* check style fix

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* fix check style

* [Feature-3682][ui]Add form-create plug-in and alarm group management add sample demo (#3683)

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* check style fix

* rollback test change

* rollback test change

* rollback dao pom change

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* add ut to pom.xml

* add upgrade schema to global schema

* fix ut failed

* fix ut failed

* fix ut failed

* fix ut failed

* add test EmailAlertPluginTest to pom.xml

* fix ut failed

* fix ut failed

* fix check style

* update license header to presto license header

* presto license header not check

* fix ut coverage

* fix ut coverage

* fix ut

* fix ut

* fix ut

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage
Co-authored-by: Nbreak60 <790061044@qq.com>

* The tenant management module ui is replaced with element-ui

* fix

* fix

* fix

* fix

* fix

* modify

* fix
Co-authored-by: Ngaojun2048 <32193458+gaojun2048@users.noreply.github.com>

* the alert module support service.

* the alert module support service.

* Delete blank lines.

* add code checkstyle.

* Solve the sonar bug.

* Re-execute build.

* add test.

* update ut.

* add test class.

* update test.

* [feature#3356] alert-spi support DingTalk&WeChat (#3869)

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature][ui]Alert plugin design (#3734)

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [Feature-3682][ui]Add form-create plug-in and alarm group management add sample demo (#3683)

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature][ui] Add alarm instance page

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [Feature-3189][alert,spi,dao,plugin-api] base code of dolphinscheduler spi and alert plugin implement (#3601)

* DS SPI

* Add DolphinScheduler SPI , and rebuilt the code of the Alert plug-in based on SPI

* Add DolphinScheduler SPI , and rebuilt the code of the Alert plug-in based on SPI

* add TODO

* delete

* compile

* spi commit

* Plugin Alert

* fix some bug

* add todo

* change web ui from alpacajs to form-create

* remove module

* add plugin schema

* add license header

* update alert and spi module version

* update the alert plugin sub module version

* comment the maven.local.repository param

* move utils from spi to common module

* add license header

* add license header and delete some chinese comment

* update spi packages

* delete no use alert_xx.properties

* update mysql.connector.version back to 5.1.34

* delete no use comment in pom.xml

* update email stmp password

* add license

* add semicolon to sql/upgrade/1.4.0_schema/mysql/dolphinscheduler_ddl.sql file

* format the code style

* format new clase file with checkstyle

* update plugin params to Builder model

* move JSONUtils to SPI because plugin can not dependency common module

* move JSONUtils to SPI because plugin can not dependency common module

* delete collection dependency

* replace PluginParamsTransfer to spi PluginParamsTransfer

* update dolphinscheduler-maven-plugin to 1.0.0

* update license

* update apache-rat-plugin add exclude '.iml' file

* check license

* ArtifactResolver only use in development and configPlugins is not empty

* ArtifactResolver only use in development and configPlugins is not empty

* ArtifactResolver only use in development and configPlugins is not empty

* default datasource should be postgresql

* add license files

* add license files

* postgresql port should be 5432

* postgresql test

* mv show_type to spi

add license header to AlertConstants

* check style fix

* copy check style file from branch dev

* alert show_type set by plugin

* alert show_type set by plugin

* add PluginDefineMapper to dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/registry/DependencyConfig.java

* add Bean to TaskCallbackServiceTestConfig

* add Bean to TaskCallbackServiceTestConfig

* fix check style

* check style fix

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* fix check style

* [Feature-3682][ui]Add form-create plug-in and alarm group management add sample demo (#3683)

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* check style fix

* rollback test change

* rollback test change

* rollback dao pom change

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* add ut to pom.xml

* add upgrade schema to global schema

* fix ut failed

* fix ut failed

* fix ut failed

* fix ut failed

* add test EmailAlertPluginTest to pom.xml

* fix ut failed

* fix ut failed

* fix check style

* update license header to presto license header

* presto license header not check

* fix ut coverage

* fix ut coverage

* fix ut

* fix ut

* fix ut

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage

* fix ut coverage
Co-authored-by: Nbreak60 <790061044@qq.com>

* [feature#3356] alert-spi support DingTalk

this closes # 3356

* add test

* code style

* we chat alert

* support we chat alert

* support we chat alert

* support we chat alert,update ding talk alert

* code style

* add test

* code style

* clean old code

* clean old code

* code smell

* code style

* add test

* simple config

* code style

* code style

* code style

* delete old file

* fix log content error
Co-authored-by: Nbreak60 <790061044@qq.com>
Co-authored-by: Ngaojun2048 <32193458+gaojun2048@users.noreply.github.com>

* [FEATURE#4029] alert spi support script alert

this closes #4029

* code style

* code smell

* add test

* code style

* code smell

* code style

* fix name error

* init sms plugin

* modify http type

* delete dolphinscheduler-alert-sms plugin

* dolphinscheduler plugin need add <package>dolphinscheduler-plugin</package> in the pom.xml file

* delete alert http plugin (#4152)

delete alert http plugin (#4152)
This part of the code was merged by mistake, so I need to delete it

* [Feature-3749][Alert-SPI] SqlTask should send notifications by alert server api (#4080)

* add sqltask send sync alert server.

* update alert-sms license.

* update AlertServer test.

* remote EmailAlertPluginTest.

* update sqltask.

* update test class.

* [Alert plugin design] add http alert plugin (#4165)

* add http alert plugin

* [Feature-3311] Add alert plugin instance function (#4038)

* [Feature-#3252][build]plugins need put in plugins dir when install (#4259)

Update maven build, put the alert plugins in the ${install_dir}/lib/plugin/alert/${plugin_module_name} directory
(assembly build and rpm build).
Note: When adding a new plug-in, it must be reflected in provisio/dolphinscheduler.xml.

this closes #3252

* [Feature#4310][Alert-SPI] Plug-ins containing UI components provide display pages (#4311)

* [Feature#4310][Alert-SPI] Plug-ins containing UI components provide display pages

*Some plugins (such as alert plugin) need to provide UI interfaces to users.
*We use from-creat to dynamically generate UI interfaces. Related parameters are mainly provided by pluginParams.
*From-create can generate dynamic ui based on this parameter.

this closes #4310

* add license head

* rename

* add ut

* add license

* add query plugin detail interface

* fix error

* [Feature-#3828][server] Delete recipients and CCs in the process defi… (#4303)

* [Feature-#3828][server] Delete recipients and CCs in the process definition and select the associated alert group instead

* The specific alarm instance associated with the alert group
* The process definition only associates the alert group, and does not care about the specific alarm instance.

this closes #3828

* remove test cc

* remove test cc

* fix test error

* add sql upgrade script
delete alert column(show_type、alert_type、re、cc)

* code style

* update test
Note the statement to delete the column, and provide related instructions

* delete AlertGroup field(alert_type)

* fix ut error

* fix ut error

* fix ut error

* code style

* delete api-doc receiverCC

* delete UserAlertGroupMapper

* delete UserAlertGroup

* delete UserAlertGroupApi

* alert group add coulmn user_id

* alter user_id to create_user_id

* userinfo remove alert group info

* Replace the front-end code of the plugin branch with the front-end code of the dev branch (#4353)

* Replace the front-end code of the plugin branch with the front-end code of the dev branch

* Merge dev to alert_plugin_design (#4351)

* fixed queryProcessInstanceListPaging query slow (#3893)

because queryProcessInstanceListPaging has contain longtext type field by instance.*,so queryProcessInstanceListPaging query slow , but longtext field not used.

* fixed  queryTaskInstanceListPaging query slow (#3892)

because queryTaskInstanceListPaging  has contain longtext  type field  by instance.*,so  queryTaskInstanceListPaging query slow , but longtext  field not used.

* add verify tenant name cannot contain special characters. (#3865)

* [Fix][Docker] fix startup.sh variables cannot reference in single quotes. (#3895)

* [Fix][Docker] fix startup.sh variables cannot reference in single quotes.(#3894)
Signed-off-by: NYoungMan <bushengquan@gmail.com>

* Update Dockerfile

update the  comment
and delete the maridb client
Co-authored-by: Ndailidong <dailidong66@gmail.com>

* [ambari-plugin]change version 1.3.2 to 1.3.3 (#3935)

* [CodeClean][DAO]Remove redundant comments (#3939)

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* dag  add close button

* reset last version

* reset last version

* dag add close buttion

dag add close buttion

* update  CLICK_SAVE_WORKFLOW_BUTTON  xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* Update CreateWorkflowLocator.java

modify submit workflow button

* Update CreateWorkflowLocator.java

* Update CreateWorkflowLocator.java

modify CLICK_ADD_BUTTON

* Update CreateWorkflowLocator.java

delete print

* Update CreateWorkflowLocator.java

1

* Update CreateWorkflowLocator.java

1

* Setting '-XX:+DisableExplicitGC ' causes netty memory leaks

in addition

update '- XX: largepagesizeinbytes = 128M' to '- XX: largepagesizeinbytes = 10M'

* Update dag.vue

* Update dag.vue

* Update dag.vue

* Update CreateWorkflowLocator.java

* Revert "Setting '-XX:+DisableExplicitGC ' causes netty memory leaks"

This reverts commit 3a2cba7a

* Setting '-XX:+DisableExplicitGC ' causes netty memory leaks

in addition

update '- XX: largepagesizeinbytes = 128M' to '- XX: largepagesizeinbytes = 10M'

* Update dolphinscheduler-daemon.sh

* Remove redundant comments
ProcessInstanceMapper# queryProcessInstanceListPaging

* Remove redundant comments
ProcessInstanceMapper# queryProcessInstanceListPaging
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nxingchun-chen <55787491+xingchun-chen@users.noreply.github.com>

* fix bug:3615 After the task is executed successfully, but the next task has not been submitted, stop the master

* When running a task, the resource file is lost, which results in an error

* When running a task, the resource file is lost, which results in an error

* When running a task, the resource file is lost, which results in an error

* [Fix][api] Add queryProjectCreatedAndAuthorizedByUser function (#3658)

* fix getLoginUserCreated bug

* fix getLoginUserCreated bug 1

* fix checkstyle

* modify function name

* modify comment

* fix unit test error

* rollback sqoop task hive target file
Co-authored-by: Nsunchaohe <sunzhaohe@linklogis.com>
Co-authored-by: Ndailidong <dailidong66@gmail.com>

* When running a task, the resource file is lost, which results in an error

* When running a task, the resource file is lost, which results in an error

* [fixBug-3964][ui]Switch back and forth over timeout alarm, the selected value is empty

* solve too many files, close logClientService (#3971)

* fix #3966 sub process doesnot send alert mail after process instance ending. (#3972)
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [Fix-#3618][server] resolve task executed finished but not release the file handle (#3975)

* [Fix-#3618][server] resolve task executed finished but not release the file handle

* [Fix-#3618][server] resolve task executed finished but not release the file handle

* [Fix-#3958][api] files should not be created successfully in the directory of the authorized file

* [FIX-3966] The timeout warning does not take effect in sub_process (#3982)

* fix #3966 sub process doesnot send alert mail after process instance ending.

* fix bug 3964: sub_process The timeout warning does not take effect
add timeout warning for sub_process/dependent task.

* fix code smell

* fix code smell

* fix code smell

* update worker group inherit from parent
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [fix-#3962][api] Avoid ClassCastException for LoggerService.queryLog(). (#3963)

* Enhance user experience, add close button to file details page

* [Test-3557][API] full cover DataAnalysisServiceImpl (#3605)

* generate equals and hashCode method

* make up for the state of oblivion

* simplify countQueueState method

* delete try catch, because this never throw exception

* full cover DataAnalysisServiceImpl

* improve test coverage

* adjust code style

* simplify countCommandState method

* reduce duplication

* simplify countTaskDtos method

* Update DataAnalysisServiceImpl.java
Co-authored-by: Ndailidong <dailidong66@gmail.com>

* fix import dolphinscheduler_mysql.sql insert admin user data

* [FIX-3929] condition task would post wrong tasks when failover. (#3999)

* fix #3966 sub process doesnot send alert mail after process instance ending.

* fix bug 3964: sub_process The timeout warning does not take effect
add timeout warning for sub_process/dependent task.

* fix code smell

* fix code smell

* fix code smell

* update worker group inherit from parent

* remove stdout in logback configuration

* fix bug #3929 condition task would post error when failover.

* remove unused test

* add comments

* add skip node judge
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [FIX-3929]  because of no lock, start up failover would dispatch two same tasks. (#4004)

* fix #3966 sub process doesnot send alert mail after process instance ending.

* fix bug 3964: sub_process The timeout warning does not take effect
add timeout warning for sub_process/dependent task.

* fix code smell

* fix code smell

* fix code smell

* update worker group inherit from parent

* remove stdout in logback configuration

* fix bug #3929 condition task would post error when failover.

* remove unused test

* add comments

* add skip node judge

* fix bug 3929: because of no lock, start up failover would dispatch two same tasks.
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* revert pom version to 1.3.3-release

* [maven-release-plugin] prepare release 1.3.3

* [maven-release-plugin] prepare for next development iteration

* the resources API document does not match the interface parameters

* [release]revert pom version to 1.3.3-release

* fix bug 4010: remove failed condition tasks from error-task-list. (#4011)
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [maven-release-plugin] prepare release 1.3.3

* [maven-release-plugin] prepare for next development iteration

* fix bug

* reset code

* Update udfs.vue

* [Feature-3941][ui] Remove tenant name  (#3949)

* FeatureUI-3941: Removed Tenant

* FeatureUI-3941: Removed tenantName in the suggested pages

* FeatureUI-3941: Updated the suggested files

* FeatureUI-3941: Updated the TenantController

* FeatureUI-3941: Updated the TenantController and the pom.xml

* FeatureUI-3941: Updated the TenantControllerTest

* [Improvement][script] daemon script usage (#3968)

* Improvement daemon script usage

* don't remove status command

don't remove status command
Co-authored-by: Ndailidong <dailidong66@gmail.com>

* fix #3688, Optimization of table building statements (#3689)

* merge from 1.3.3-release

* merge from 1.3.3-release

* [Improvement-4012][common/remote] Json util code integration,remove the remote module json util (#4013)

* Json util code integration,remove the remote module json util.

* update code checkstyle.

* update code checkstyle.

* add code checkstyle.

* add test class.

* update JSONUtils class.

* update JSONUtils class.

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* refactor code style

* refactor code style

* refactor code style

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* refactor ut test

* refactor ut test

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* fix #3900 kill multi yarn app in one job

* refactor ut

* merge from 1.3.3-release

* refactor ut

* refactor ut

* refactor

* refactor

* refactor code style

* refactor code style

* refactor code style

* refactor code style

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* add ProcessUtils UT

* refactor code style

* refactor code style

* refactor code style

* refactor code style

* [Draft][Merge][133-dev]133 merge dev (#4031)

* [Feture-3327][ui]Add the function of re-uploading files in the resource center

* [Feture-3327][ui]Add the function of re-uploading files in the resource center (#3394)

* Before creating a workflow, clear the canvas

* [Fix-3256][ui] herry pick commit from dev for Fix admin user info update error (#3306)

* [Feture-3327][ui]Add the function of re-uploading files in the resource center
Co-authored-by: Nwuchunfu <319355703@qq.com>

* [Improvement-3327][api]support re-upload the resource file (#3395)

* [Fix-3390][server]Running hive sql task need find the hdfs path correctly (#3396)

* [Fix-3390][api]Running hive sql task need find the hdfs path correctly

* [Fix-3390][api]Running hive sql task need find the hdfs path correctly

* update soft version

* hive UDF function to modify the background color

* fix

* fix bug: Fix master task dependency check bug

* cancel spark task version check (#3406)
Co-authored-by: NEights-Li <yelli.hl@gmail.com>

* [Bug][ui]Fix front-end bug #3413

* [Feature][ambari_plugin]support one worker can belongs different worker groups when execute install script (#3410)

* Optimize dag

* Update actions.js (#3401)

* [Fix-3256][ui] Fix admin user info update error (#3425) (#3428)

* [PROPOSAL-3139] Datasource selection changes from radio to select

* [PROPOSAL-3139] Datasource selection changes from radio to select

* [BUG FIX] issues #3256

* [BUG FIX] issues #3256

* [BUG FIX] issues #3256

* [Fix-3256][ui] Fix admin user info update error

* [Fix-3256][ui] Fix admin user info update error

* [Fix-3256][ui] Fix admin user info update error

* [Fix-3256][ui] Fix admin user info update error

* reset createUser.vue

* [Fix-3256][ui] Fix admin user info update error
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nwuchunfu <319355703@qq.com>
Co-authored-by: Ndailidong <dailidong66@gmail.com>

* [Fix-3433][api]Fixed that release the imported process definition which version is below 1.3.0 will be failure

* dag connection add check

* fix

* [Fix-3423][dao][sql]Fixed that the resource file of the task node can't be found when upgrade from 1.2.0 to 1.3.x (#3454)

* Remove node deep monitoring

* If worker group id is null,don't need to set the value of the worker group (#3460)

* [Fix-3423][dao][sql]Fixed that the resource file of the task node can't be found when upgrade from 1.2.0 to 1.3.x

* [Fix-3423][dao]If worker group id is null,don't need to set the value of the worker group

* [ui]Code optimization

* fix

* fix

* [fix-3058][ui]Move rtTargetArr to jsPlumbHandle.js

* [optimization][ui]Prevent the shell script input box from being empty

* [Fix-3462][api]If login user is admin,need list all udfs (#3465)

* [Fix-3462][api]If login user is admin,need list all udfs

* [Fix-3462][api]add the test on the method of QueryUdfFuncList

* [Fix-3462][api]fix the code smell

* [Fix-3462][api]fix the code smell

* [Fix-3462][api]fix the code smell

* [Fix-3463][api]Fixed that run the sql task will be failure after rename the udf resource (#3482)

* [fixBug-3058][ui]Fix connection abnormalities in historical workflow instance data

* [Feture-3327][ui]Add the function of re-uploading files in the udf subdirectory

* fix bug: Fix master task dependency check bug (#3473)
Co-authored-by: Nlenboo <baoliang@analysys.com.cn>

* [maven-release-plugin] prepare release 1.3.2

* [maven-release-plugin] prepare for next development iteration

* fix ci_e2e fail (#3497)

* [Fix-3469][api]Should filter the resource by the different program type (#3498)

* [Fix-3463][api]Fixed that run the sql task will be failure after rename the udf resource

* [Fix-3469][api]Should list python file and jar file

* [Fix-3469][api]Should filter the resource by the different program type

* [Fix-3469][api]fix the code smell

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback (#3499)

* [Feature] JVM parameter optimization , related issue #3370

* [Feature] JVM parameter optimization , related issue #3370

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>

* [maven-release-plugin] prepare release 1.3.2

* [maven-release-plugin] prepare for next development iteration

* [Fix-3469][ui]The value of maintenance resources and the filtering of resources according to different program types

* fix

* Revert "fix ci_e2e fail (#3497)"

This reverts commit e367f90b.

* test

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback (#3503)

* [Feature] JVM parameter optimization , related issue #3370

* [Feature] JVM parameter optimization , related issue #3370

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback

* test

* test release 1.3.2 version rollback
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>

* [maven-release-plugin] prepare release 1.3.2

* [maven-release-plugin] prepare for next development iteration

* test release 1.3.2 version rollback (#3504)

* [Feature] JVM parameter optimization , related issue #3370

* [Feature] JVM parameter optimization , related issue #3370

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback

* test

* test release 1.3.2 version rollback
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>

* [maven-release-plugin] prepare release 1.3.2

* [maven-release-plugin] prepare for next development iteration

* fix ds muti-level directory in zk, which lead to fail to assign work

* add login user check some actions in api

* [Hotfix][ci] Fix e2e ci docker image build error

* modify tag 1.3.0 to HEAD

* modify tag 1.3.0 to HEAD (#3525)

* [Feature] JVM parameter optimization , related issue #3370

* [Feature] JVM parameter optimization , related issue #3370

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback

* test

* test release 1.3.2 version rollback

* modify tag 1.3.0 to HEAD
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>

* remove OGNL part of the mybaits notice (#3526)

* [maven-release-plugin] prepare release 1.3.2

* [maven-release-plugin] prepare for next development iteration

* release 1.3.2 version rollback (#3527)

* [Feature] JVM parameter optimization , related issue #3370

* [Feature] JVM parameter optimization , related issue #3370

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback

* test

* test release 1.3.2 version rollback

* modify tag 1.3.0 to HEAD
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>

* [ui]Script input box to modify the delay loading time

* fix

* fix

* fix

* fix

* modify general user can't create token

* [ui]It is forbidden to select non-existent resources and modify the tree display data format

* modify general user can't create token (#3533)

* [Feature] JVM parameter optimization , related issue #3370

* [Feature] JVM parameter optimization , related issue #3370

* test release 1.3.2 version rollback

* test release 1.3.2 version rollback

* test

* test release 1.3.2 version rollback

* modify tag 1.3.0 to HEAD

* modify general user can't create token
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>

* if task is null , set task type is null instead of "null"

* [Fix-3536][api]If user didn't have tenant,create resource directory will NPE (#3537)

* [Fix-3536][api]If user didn't have tenant,create resource will NPE

* [Fix-3536][api]If user didn't have tenant,create resource directory will NPE

* modify general user can't create,delete,update token (#3538)
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>

* [ui]Resource delete OK button to increase loading, change the number of homepage display cursor

* fix

* [Fix-3616][Server] when worker akc/response master exception , async retry (#3748)

* [fixbug][ui]Repair the master and worker management instrument display

* [Fix-3238][docker]Fix that can not create folder in docker with standalone mode (#3741)

* [fixbug][ui]Remove non-existent or deleted resources disabled

* [fixBug-3621][ui]If the workflow instance status is executing status, it is forbidden to select

* [fix-3553][ui]Repair click workflow connection, select the entire path

* fix

* fix

* [Fix-3238][docker]Fix that can not create folder in docker with standalone mode

* [Fix-3616][Server] when worker akc/response master exception , async retry (#3776)

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>

* The batch delete function in the workflow definition and workflow instance pages cannot be canceled if selected.

* [Improvement-3720][ui] js mailbox verification fix

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect (#3784)

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* The batch delete function in the workflow definition and workflow instance pages cannot be canceled if selected.

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>
Co-authored-by: Nzhuangchong <zhuangchong8@163.com>
Co-authored-by: NJinyLeeChina <42576980+JinyLeeChina@users.noreply.github.com>

* [Fix-3124][docker]Fix that can not build a docker image on windows (#3765)

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect (#3786)

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* The batch delete function in the workflow definition and workflow instance pages cannot be canceled if selected.

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>
Co-authored-by: Nzhuangchong <zhuangchong8@163.com>
Co-authored-by: NJinyLeeChina <42576980+JinyLeeChina@users.noreply.github.com>

* [Fix-3258][Security][Worker group manage] Connot get create time and update time,report DateTimeParseException (#3787)

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* [Fix-3616][Server] when worker akc/response master exception , async retry

* The batch delete function in the workflow definition and workflow instance pages cannot be canceled if selected.

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect

* [Fix-3549] [Server][sqlTask]The alias column in the query SQL does not take effect

* [BugFixed] issue #3258 (#3265)

* 'ExecutionStatus'

* '3258'

* Update WorkerGroupServiceTest.java

* Delete UserState.java

* Delete ResourceSyncService.java

* Delete core-site.xml

* Delete hdfs-site.xml
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@outlook.com>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>
Co-authored-by: Nzhuangchong <zhuangchong8@163.com>
Co-authored-by: NJinyLeeChina <42576980+JinyLeeChina@users.noreply.github.com>
Co-authored-by: Ndailidong <dailidong66@gmail.com>

* [fixBug-3792][ui]Click on the sidebar to adapt the width of the pie chart on the project homepage

* [Bug-3713][HadoopUtils] catfile method Stream not closed  (#3715)

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* dag  add close button

* reset last version

* reset last version

* dag add close buttion

dag add close buttion

* update  CLICK_SAVE_WORKFLOW_BUTTON  xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* Update CreateWorkflowLocator.java

modify submit workflow button

* Update CreateWorkflowLocator.java

* Update CreateWorkflowLocator.java

modify CLICK_ADD_BUTTON

* Update CreateWorkflowLocator.java

delete print

* Update CreateWorkflowLocator.java

1

* Update CreateWorkflowLocator.java

1

* Setting '-XX:+DisableExplicitGC ' causes netty memory leaks

in addition

update '- XX: largepagesizeinbytes = 128M' to '- XX: largepagesizeinbytes = 10M'

* Update dag.vue

* Update dag.vue

* Update dag.vue

* Update CreateWorkflowLocator.java

* Revert "Setting '-XX:+DisableExplicitGC ' causes netty memory leaks"

This reverts commit 3a2cba7a

* Setting '-XX:+DisableExplicitGC ' causes netty memory leaks

in addition

update '- XX: largepagesizeinbytes = 128M' to '- XX: largepagesizeinbytes = 10M'

* Update dolphinscheduler-daemon.sh

* catfile method Stream not closed

* catfile method Stream not closed
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nxingchun-chen <55787491+xingchun-chen@users.noreply.github.com>

* [Fix-#3713][common]Fix that catfile method Stream not closed

* [Fix-#3713][common]Fix that catfile method Stream not closed (#3810)

* [Bug-3713][HadoopUtils] catfile method Stream not closed  (#3715)

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* fix bug

Delete invalid field: executorcores

Modify verification prompt

* dag  add close button

* reset last version

* reset last version

* dag add close buttion

dag add close buttion

* update  CLICK_SAVE_WORKFLOW_BUTTON  xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* updae CLICK_SAVE_WORKFLOW_BUTTON xpath

* Update CreateWorkflowLocator.java

modify submit workflow button

* Update CreateWorkflowLocator.java

* Update CreateWorkflowLocator.java

modify CLICK_ADD_BUTTON

* Update CreateWorkflowLocator.java

delete print

* Update CreateWorkflowLocator.java

1

* Update CreateWorkflowLocator.java

1

* Setting '-XX:+DisableExplicitGC ' causes netty memory leaks

in addition

update '- XX: largepagesizeinbytes = 128M' to '- XX: largepagesizeinbytes = 10M'

* Update dag.vue

* Update dag.vue

* Update dag.vue

* Update CreateWorkflowLocator.java

* Revert "Setting '-XX:+DisableExplicitGC ' causes netty memory leaks"

This reverts commit 3a2cba7a

* Setting '-XX:+DisableExplicitGC ' causes netty memory leaks

in addition

update '- XX: largepagesizeinbytes = 128M' to '- XX: largepagesizeinbytes = 10M'

* Update dolphinscheduler-daemon.sh

* catfile method Stream not closed

* catfile method Stream not closed
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nxingchun-chen <55787491+xingchun-chen@users.noreply.github.com>

* [Fix-#3713][common]Fix that catfile method Stream not closed
Co-authored-by: NBoYiZhang <39816903+BoYiZhang@users.noreply.github.com>
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nxingchun-chen <55787491+xingchun-chen@users.noreply.github.com>

* [Fix-#3487][api、dao] cherry pick from dev to fix that create folder duplicate name under multithreading

* [Hotfix-3131][api] Fix the new tenant already exists prompt (#3132)

* Bugfix: Fix the new tenant already exists prompt

* Feature: Add test cases

* Update TenantServiceTest.java
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@outlook.com>

* Set up JDK 11 for SonarCloud in github action. (#3052)

* Set up JDK 11 for SonarCloud in github action.

* Fix javadoc error with JDK 11.

* Prevent Javadoc from stopping if it finds any html errors.

* [fixBug-3621][ui]Select the batch checkbox to unfilter the instances in the executing state

* add verify tenant name cannot contain special characters.

* [fixBug-3840][ui]The tenant code only allows letters or a combination of letters and numbers

* fix

* fix

* fix

* [Fix-#3702][api] When re-upload the resource file but don't change the name or desc,it need replace the origin resource file. (#3862)

* [Fix-#3702][api] When re-upload the resource file but don't change the name or desc,it will not replace the origin resource file.

* [Fix-#3702][api] When re-upload the resource file but don't change the name or desc,it will not replace the origin resource file.

* [fixbug-3621][ui]Workflow instance ready to stop and ready to suspend state prohibits checking

* [fixbug-3887][ui]Fix missing English translation of re-upload files

* add process define name verify. (#3879)

* Revert "[1.3.3-release][fix-3835][ui] When the tenantName contains "<", the tenant drop-down list is blankadd verify tenant name cannot contain special characters."

* revert pr 3872

* [FIX-3617][Service]after subtask fault tolerance, 2 task instances are generated (#3830)

* fix bug(#3617): after subtask fault tolerance, 2 task instances are generated.

* delete unused code

* update code smell

* refactor sub work command process

* add process service ut

* add license header

* fix some code smell

* chang ut java8 to java11

* update sonar to java11

* copy ut config from dev

* remove checkstyle

* revert to 1.3.3

* change proess service test to executor service

* add process service test

* add process service test

* revert

* revert

* add comments

* change dev to 1.3.3-release

* revert
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [Fix-#3487][sql] add dolphinscheduler_dml.sql under 1.3.3_schema (#3907)

* [FIX-3836][1.3.3-release-API] process definition validation name interface prompt information error  (#3899)

* fix bug : error message

* fix code smell

* fix code smell

* [FIX_#3789][remote]cherry pick from dev to support netty heart beat

* [FIX_#3789][remote]cherry pick from dev to support netty heart beat

* [FIX_#3789][remote]cherry pick from dev to support netty heart beat (#3913)

* [FIX_#3789][remote]cherry pick from dev to support netty heart beat

* [FIX_#3789][remote]cherry pick from dev to support netty heart beat
Co-authored-by: NKirs <acm_master@163.com>

* Repair check box cannot be canceled

* [fix-3843][api] When update workflow definition,if name already exists, the prompt is not friendly

* [fix-3843][api] When update workflow definition,if name already exists, the prompt is not friendly

* [fix-#3843][api]When update workflow definition,if name already exists, the prompt is not friendly (#3918)

* [FIX_#3789][remote]cherry pick from dev to support netty heart beat

* [FIX_#3789][remote]cherry pick from dev to support netty heart beat

* [fix-3843][api] When update workflow definition,if name already exists, the prompt is not friendly

* [fix-3843][api] When update workflow definition,if name already exists, the prompt is not friendly
Co-authored-by: NKirs <acm_master@163.com>

* [Fix-#3487][sql] update uc_dolphin_T_t_ds_resources_un

* Workflow definition name re-modified and added check

* [fix-#3843][api]When update workflow definition,if name already exists, the prompt is not friendly.

* update code.

* [#3931][ui]Field name optimization for spark, flink, and mr

* change version from 1.3.2-SNAPSHOT to 1.3.3-SNAPSHOT (#3934)

* [maven-release-plugin] prepare release 1.3.3

* [maven-release-plugin] prepare for next development iteration

* [ambari-plugin]change version 1.3.2 to 1.3.3 (#3935)

* fix bug:3615 After the task is executed successfully, but the next task has not been submitted, stop the master

* [fixBug-3964][ui]Switch back and forth over timeout alarm, the selected value is empty

* solve too many files, close logClientService (#3971)

* fix #3966 sub process doesnot send alert mail after process instance ending. (#3972)
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [Fix-#3618][server] resolve task executed finished but not release the file handle (#3975)

* [Fix-#3618][server] resolve task executed finished but not release the file handle

* [Fix-#3618][server] resolve task executed finished but not release the file handle

* [Fix-#3958][api] files should not be created successfully in the directory of the authorized file

* [FIX-3966] The timeout warning does not take effect in sub_process (#3982)

* fix #3966 sub process doesnot send alert mail after process instance ending.

* fix bug 3964: sub_process The timeout warning does not take effect
add timeout warning for sub_process/dependent task.

* fix code smell

* fix code smell

* fix code smell

* update worker group inherit from parent
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* fix import dolphinscheduler_mysql.sql insert admin user data

* [FIX-3929] condition task would post wrong tasks when failover. (#3999)

* fix #3966 sub process doesnot send alert mail after process instance ending.

* fix bug 3964: sub_process The timeout warning does not take effect
add timeout warning for sub_process/dependent task.

* fix code smell

* fix code smell

* fix code smell

* update worker group inherit from parent

* remove stdout in logback configuration

* fix bug #3929 condition task would post error when failover.

* remove unused test

* add comments

* add skip node judge
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [FIX-3929]  because of no lock, start up failover would dispatch two same tasks. (#4004)

* fix #3966 sub process doesnot send alert mail after process instance ending.

* fix bug 3964: sub_process The timeout warning does not take effect
add timeout warning for sub_process/dependent task.

* fix code smell

* fix code smell

* fix code smell

* update worker group inherit from parent

* remove stdout in logback configuration

* fix bug #3929 condition task would post error when failover.

* remove unused test

* add comments

* add skip node judge

* fix bug 3929: because of no lock, start up failover would dispatch two same tasks.
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* revert pom version to 1.3.3-release

* [maven-release-plugin] prepare release 1.3.3

* [maven-release-plugin] prepare for next development iteration

* [release]revert pom version to 1.3.3-release

* fix bug 4010: remove failed condition tasks from error-task-list. (#4011)
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [maven-release-plugin] prepare release 1.3.3

* [maven-release-plugin] prepare for next development iteration

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* refactor code style

* refactor code style

* refactor code style

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* refactor ut test

* refactor ut test

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* refactor ut

* merge from 1.3.3-release

* refactor ut

* refactor ut

* refactor

* refactor

* refactor code style

* refactor code style

* refactor code style

* refactor code style

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* merge from 1.3.3-release

* refactor code style
Co-authored-by: Nbreak60 <790061044@qq.com>
Co-authored-by: Nwuchunfu <319355703@qq.com>
Co-authored-by: Nlgcareer <18610854716@163.com>
Co-authored-by: Nxingchun-chen <55787491+xingchun-chen@users.noreply.github.com>
Co-authored-by: Nlenboo <baoliang@analysys.com.cn>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>
Co-authored-by: NYelli <amarantine@my.com>
Co-authored-by: NEights-Li <yelli.hl@gmail.com>
Co-authored-by: NJinyLeeChina <42576980+JinyLeeChina@users.noreply.github.com>
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@outlook.com>
Co-authored-by: NXiaotaoYi <v-xiayi@hotmail.com>
Co-authored-by: NYichao Yang <1048262223@qq.com>
Co-authored-by: Nzhuangchong <zhuangchong8@163.com>
Co-authored-by: NBoYiZhang <39816903+BoYiZhang@users.noreply.github.com>
Co-authored-by: Nmuzhongjiang <mu_zhongjiang@163.com>
Co-authored-by: NJave-Chen <baicai.chen@gmail.com>
Co-authored-by: Nzhuangchong <zhuangchong6@163.com>
Co-authored-by: Nzhuangchong <37063904+zhuangchong@users.noreply.github.com>
Co-authored-by: NKirs <acm_master@163.com>
Co-authored-by: Nlgcareer <lgcareer@apache.org>
Co-authored-by: Nwulingqi <wulingqi@baijiahulian.com>

* Revert "[Draft][Merge][133-dev]133 merge dev (#4031)" (#4057)

This reverts commit ad2d9f99.

* [Fix][API] Condition task null pointer exception (#4056)

* add ProcessUtils UT

* modify ProcessUtils & ProcessUtilsTest

* Enhance user experience, add close button, return to the previous page (#4006)
Co-authored-by: Nzhanglong <zhanglong@ysstech.com>

* [FIX_BUG][server-test] dismiss of server warm-up time in RoundRobinSelectorTest (#4067)

* [Fix][api] Fix build parameter error of sqlserver when create. (#4015)

* [fix-#3962][api] Avoid ClassCastException for LoggerService.queryLog().

* [Fix][api] Fix build parameter error of sqlserver when create.

* [Feature-3985][Datax] Datax supports setting up running memory (#3986)

* Datax supports setting up running memory

* Datax supports setting up running memory

* Datax supports setting up running memory

* When running a task, the resource file is lost, which results in an error

* add unit test

* add unit test

* add unit test

* add test unit

* add test unit

* add test unit

* fix code smell

* add test unit

* add test unit

* [Improvement-3767][api] Task instance supports query by process instance name (#3825)

* Task instance supports query by process instance name.

* add test code checkstyle.

* add test param.

* resolve the sonar duplication check.

* solve logger single-line string exceeds 200 characters.

* resolve the sonar check.

* Resolve code conflicts.
Co-authored-by: Nzhuangchong <zhuangchong8@163.com>

* deal with magic value

* [Feature-4050][server] Spark task support udv inject (#4061)

* #4050 spark task support udv inject

* modify spark task UT

* modify sparkTaskExecutionCtx

* add exp for spark task get main jar method

* deal with magic value

* [Improvement-3471][common] JSONUtils.toMap It is not necessary to check whether the JSON method is empty again. #3471 (#3481)

* JSONUtils.toMap call improvement.

* [Fix-4054][Api] Fix The last week of the month for adding/editing timing, preview and save timing will report an error

* 解决单独执行子节点空指针的问题

* using OSUtils.execCmd when kill yarn app

* 解决单独执行子节点空指针的问题(增加checkstyle)

* 解决单独执行子节点空指针的问题(增加checkstyle)

* [FIX-#4083][server]fix taskInstance state change error
Concurrent processing of ack message and result message causes the execution sequence to be wrong

# this close # 4083

* code style

* fix replaceNRTtoUnderline NullPointerException #4098 (#4100)

* fix replaceNRTtoUnderline NullPointerException

* add  unit Test

* add taskResponseTest

* add taskResponseTest

* code smell

* Time is too small and the task is not finished

* Time is too small and the task is not finished

* [FIX-4034][server] fix sqoop import fail (#4036)

* fix #4043, sqoop import query fail

* fix #4043, sqoop task hard code & code style

* add license for SqoopConstants

* add private constructor for SqoopConstants

* fixed sqoop mysql pwd have special character

* fix checkstyle

* fix sqoop task log

* remove unused constants

* Time is too small and the task is not finished

* Time is too small and the task is not finished

* test

* remove assert

* test

* test

* fix task instance status judgment error

* fix: security page disappear delay problem when force refresh under GENERAL_USER

* improvement: resovle download url with resolveURL to prevent change of apiPrefix

* fix sqoop task jdbc string contains special char (#4105)

* [Bug][Common] read file garbled (#3479)

* fix bug : Random code problem
Co-authored-by: Nzhanglong <zhanglong@ysstech.com>

* [Improvement-3933][db operation] Improve the performance of sql query (#3940)

* optimize select * case

* emove redundancy

* bug fixed

* Update en_US.js

* Update startup.sh

* optimize

* optimize code

* optimize

* bug fixed

* add ut

* bug fixed

* bug fixed

* bug fixed

* bug fixed

* Delete WorkFlowLineageMapper.xml

* Delete createTenement.vue

* recove wrongly deleted file

* Update WorkFlowLineageMapper.xml

* Update createTenement.vue

* [Feature][API]enable response resources gzip compression (#4121)

* enable response compression

* add server.compression.mime-types with default value explicitly

* [Improvement][API] ignore noNodeException when get worker groups (#4120)

* ignore noNodeException when get worker groups

* add ut

* [Improvement][Code style] FIX SPELL WAITTING TO WAITING , etc. (#4118)

* FIX SPELL

* FIX SPELL AND  Optimizing code conventions

* add ut  cannot construct process instance, return null;

* add ut testExportProcessMetaData

* add ut testExportProcessMetaData

* add ut testImportProcessSchedule

* add ut MasterExecThreadTest

* add ut MasterExecThreadTest

* add ut testSubProcessViewTree

* add ut testComplementWithStartNodeList

* add ut testRecurseFindSubProcessId

* add ut testRecurseFindSubProcessId

* add ut testRecurseFindSubProcessId

* [FIX#4033] $[] conflicts with mysql keywords (#4111)

* [FIX#4033] $[] conflicts with mysql keywords
We currently only use this symbol for dates, so I filtered out the number type.
this close #4033

* test

* fix error

* split sqoop import hive database and table (#4141)

* upgrade quartz version to 2.3.0

* add HikariCP-java6,c3p0,mchange-commons-java license

* upgrade jackson version to 2.9.10

* remove c3p0,mchange-commons-java license

* update Check code style

* update  code style

* Update pom.xml

* Update pom.xml

* Update LICENSE

not need to add HikariCP-java6

* Delete LICENSE-HikariCP-java6.txt

* Update known-dependencies.txt

* Update TaskInstanceMapper.xml

optimize page of [TaskInstance] load data slow

* [FIX-PR-4097][server-master]task ack miss (#4189)

When the message of successful execution arrives earlier than
the message of ack,
the message of ack will be discarded,
resulting in some information missing

* fix bug #4125 (#4127)

* fix bug #4125

* code style!

* code style.
Co-authored-by: Nchengp <chengp@chengp.net>

* [FIX-4190][DAO] When the amount of json data is large, the process list page display slowly. (#4201)

* fix 4190: When the amount of json data is large, process list page display slowly

* fix 4190: When the amount of json data is large, process list page display slowly

* fix 4190: When the amount of json data is large, process list page display slowly
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>

* [Fix-3457][flink] fix flink args build problem (#4166)

* [Fix][Flink] fix flink args build problem

* [Fix][Flink] fix FlinkArgsUtilsTest

* [Improvement][UI] hide version and cluster input when deployMode is local

* [common]del windows file( not support windows ) (#4204)

* del support win

* del support win

* [Feature-4138][Master] dispatch workgroup error add sleep time (#4139)

* When there are tasks with assignment failure and the number of tasks in the current task queue is less than 10, sleep for 1 second

* When there are tasks with assignment failure and the number of tasks in the current task queue is less than 10, sleep for 1 second

* fix code smell & code style

* fix code smell & code style
Co-authored-by: Nzhanglong <zhanglong@ysstech.com>

* [FIX-#4172][server-worker] kill task NPE (#4182)

* [FIX-#4172][server-worker] kill task NPE

The cache task will be sent when the Process is generated. Before that, if a kill task appears, then NPE will appear
Modification method: write into the cache when the task is received, and mark it as preData
If the task is killed before the Process is generated, delete the cache directly at this time
It will be judged before the process is generated. If the task has been killed, it will not be executed.
After the new process is created, write it into the cache, and judge again, if kill, then kill the process.

this closes #4172

* Delete the commented out code
Add spring beans

* code smell

* add test

* add test

* fix error

* test

* test

* revert

* fix error

* [Feature-3878]Replace the page with element-ui (#4065)

* [Feature-3878]Introduce elment-ui and replace the security center module page with elment-ui

* Change node version

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* Replace the page with element-ui

* Replace user management with elment-ui

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* Repair the last Sunday of each month

* support auto eslint for .js, .vue file on save

* update .eslintrc.yml and license check exclude .eslintignore

* fix eslint: fix syntax by npm run lint automatically

* fix eslint: fatal syntax errors

* fix eslint: expected '!==' but instead saw '!=', expected '===' but instead saw '=='

* fix eslint: Unexpected side effect in 'cacheParams' computed property

* fix eslint: assigned a value but never used

* fix eslint: component has been registered but not used

* fix eslint: unexpected mutation of prop

* fix bug: start from the setting nodes with NODE_PRE would be NPE. (#4219)

* deleted invalid code as assigned in issue 4215 (#4221)

deleted the code at following two places:
org.apache.dolphinscheduler.service.process.ProcessService#checkTaskExistsInTaskQueue
org.apache.dolphinscheduler.service.process.ProcessService#taskZkInfo

* [FIX-#3177]Task time parameter parsing error (#4224)

* [FIX-#3177]Task time parameter parsing error

rerun schedule time error

this closes #3177

* [FIX-#3177]Task time parameter parsing error

rerun schedule time error

this closes #3177

* fix sql error (#4227)

* [FIX-3177]Task time parameter parsing error (#4228)

* [FIX-3177]Task time parameter parsing error
when system.datetime !=null $[datetime] = system.datetime
else $[datetime] = current time

* remove unused import

* fix date_convert null

* fix time cover

* fix time cover

* reformat

* add ut

* [Fix][UI]: fix re-login problem in new tab and state synchronization problem in multiple tabs (#4162)

* fix(ui): re-login problem in new tab

* refresh page in new tab automatically

* support to reload router view in lightweight

* optimize visibility code

* [Improvement][UI] Add no-var rule for eslint and add 'npm run lint:fix' command (#4225)

Add no-var rule for eslint, and fix related files
Add npm run lint:fix command, which distinguished from the default command npm run lint
The behavior of command npm run lint and command npm run lint:fix should be distinguished
The first command is used to lint only, and the second one is used to lint and fix problems automatically

* [FIX][UI ]  security user state  tenantCode User Type Display abnormal (#4255)

* fix user state error

* fix userType  error

* fix tenantCode  error

* [Fix-4222][Master]Add the priority queue to ensure that tasks are submitted according to priority. (#4250)

* [Fix-4222][Master]Add the priority queue to ensure that tasks are submitted according to priority.

* [Fix-4222][Master]Add the priority queue to ensure that tasks are submitted according to priority.

* [Fix-4222][Master]Remove useless import

* [Fix-4222][Master]Reformat code style

* [Fix-4222][Master]Reformat code style

* [Fix-4222][Master]Reformat code style

* [Fix-4222][Master]add PeerTaskInstancePriorityQueueTest

* [Fix-4222][Master]Fix code smell

* [Fix-4222][Master]Reformat code style

* [Fix-4222][Master]Fix code smell
Co-authored-by: Nxingchun-chen <55787491+xingchun-chen@users.noreply.github.com>

* update bug template (#4260)

* [Improvement-4069][server] When the tenant does not exist, the task execution should throw an exception (#4108)

* when  the tenant does not exist, the task execution should throw an exception

* remote method createWorkDirAndUserIfAbsent

* set the task status failed when the tenant code does not exist.

* add taskLog.

* update check os user exists

* update TaskExecuteThreadTest test method.

* solving sonar fail.

* remove AbstractTask.getCurTaskParamsClass()and replace with TaskParametersUtils.getParameters() (#4262)

* remove getCurTaskParamsClass() in AbstractTask.java and replace it with TaskParametersUtils.getParameters()

* remove unused imports in AbstractTask.java

* reformat

* [Fix-4271][server] Fix IOException or NoSuchFileException in logger server (#4272)

* fix version funcation delete. (#4265)

* [improvement][config] Update datasource.properties,add mysql meta data template (#4266)

* Update datasource.properties

[新增]元数据mysql连接模版

* Update datasource.properties
Co-authored-by: Ndailidong <dailidong66@gmail.com>

* fix taskInstance submitTime is empty. (#4274)

* [Improvement-3878]Tenant list delete user name (#4278)

* [Fix-4268] Fix NumberFormatException when visiting a doc.html or swagger-ui.html (#4269)

* [Fix-4268] Fix NumberFormatException when visiting a doc.html or swagger-ui.html

* Fix checkstyle error

* Update swagger-models in known-dependencies.txt

* [Improvement-3878][ui]Fix the list style (#4280)

* [Improvement-3878]Tenant list delete user name

* [Improvement-3878][ui]Fix the list style

* [FIX] [UI] fix create project cancel button invalid (#4282)

* fix create project cancel button invalid

* [Improvement] Refactor code to support distributed tracing (#4270)

* Refactor code to support tracing

* Extension network protocol, support context and version
* Extension master asynchronous queue support context
* Extract scan task method from MasterSchedulerService for tracing

* fix

* fix

* add test case

* fix

* fix
Co-authored-by: Nhailin0 <hailin0@yeah.net>

* [Improvement] Add Flink job name (#4285)

* [Improvement] Add Flink job name

* fix typo

* [Improvement][ui]List vacancy optimization and icon icon repair (#4286)

* [Improvement][ui] List vacancy optimization and icon icon repair

* [FEATURE-736] integrate ldap authentication (#3743)

* [FEATURE-736] integrate ldap authentication

* add ldap authentication type
* refactor authentication with ldap and password
* add  createUser for ldap in user service
* remove duplicate password authenticator

* [Fix-4289][*] Flink name with disappeared and unescaped problem (#4290)

* fix flink name not display in process definition editor

* fix flink name not escape problem

* simplify escape method

* fix database is the mysql DB keyword. (#4295)

* fix the token management list does not display the user name. (#4302)

* Dev imp server process utils (#4263)


* Adds the comment on the WINDOWSATTERN
Co-authored-by: NKirs <acm_master@163.com>
Co-authored-by: N0002939 <licongyang@mininglamp.com>

* fix version close function does not take effect. (#4307)

* fix user management authorization operation exceptions do not prompt exception information. (#4292)

* [Fix][UI] Fix ui style problem and refactor form style (#4329)

* rename from-model to form-model

* [UI] remove duplicated css style code

* [UI] refactor css style of form model

* fix form model overflow problem in ie

* Align each item one by one in locale

* fix el-dialog width is too wide

* fix locale

* [Improvement][UI] Improve script box and dialog css style (#4331)

* [Fix-4335][UI] Fix IE 9-11 not supported

* [FIx-4338][UI] Fix invalid date problem in IE

* [Improvement] Use environment variable $DOLPHINSCHEDULE_OPTS as daemon startup arguments (#4341)
Co-authored-by: Nhailin0 <hailin0@yeah.net>

* [Fix][common] only two yarns can be selected(#4314) (#4344)

* Handling conflicts manually

* code style

* ut skip ui

* fix ut error

* fix ut error

* delete SchedulerController Unused field

* delete SchedulerController Unused field

* delete SchedulerController Unused field

* ci skip ui

* ignore AlertPluginManagerTest.java and DolphinPluginLoaderTest.java

* fix ut error

* fix ut error

* test

* code style

* replace ui

* replace ui

* replace ui

* replace ui

* fix license

* fix license
Co-authored-by: N小清 <62982788+597365581@users.noreply.github.com>
Co-authored-by: Nzhuangchong <37063904+zhuangchong@users.noreply.github.com>
Co-authored-by: Nspring-bu <37682426+spring-bu@users.noreply.github.com>
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: Nlgcareer <18610854716@163.com>
Co-authored-by: NBoYiZhang <39816903+BoYiZhang@users.noreply.github.com>
Co-authored-by: Nxingchun-chen <55787491+xingchun-chen@users.noreply.github.com>
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>
Co-authored-by: NBoYiZhang <zhangboyi_mx@163.com>
Co-authored-by: _和's avatarzixi0825 <649790970@qq.com>
Co-authored-by: Nsunchaohe <sunzhaohe@linklogis.com>
Co-authored-by: Nbreak60 <790061044@qq.com>
Co-authored-by: Nbao liang <29528966+lenboo@users.noreply.github.com>
Co-authored-by: Nt1mon <178317391@qq.com>
Co-authored-by: Nzhanglong <zhanglong@ysstech.com>
Co-authored-by: N孙继峰 <sun.jifeng@outlook.com>
Co-authored-by: Nwulingqi <wulingqi@baijiahulian.com>
Co-authored-by: Nlgcareer <lgcareer@apache.org>
Co-authored-by: NIamMujuziMoses <49279842+IamMujuziMoses@users.noreply.github.com>
Co-authored-by: 愛吃枸杞的路星河's avatarhuzekang <1040080742@qq.com>
Co-authored-by: NJinyLeeChina <42576980+JinyLeeChina@users.noreply.github.com>
Co-authored-by: NEights-LI <yelli.eights@gmail.com>
Co-authored-by: Nwuchunfu <319355703@qq.com>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>
Co-authored-by: NYelli <amarantine@my.com>
Co-authored-by: NEights-Li <yelli.hl@gmail.com>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@outlook.com>
Co-authored-by: NXiaotaoYi <v-xiayi@hotmail.com>
Co-authored-by: NYichao Yang <1048262223@qq.com>
Co-authored-by: Nzhuangchong <zhuangchong8@163.com>
Co-authored-by: Nmuzhongjiang <mu_zhongjiang@163.com>
Co-authored-by: NJave-Chen <baicai.chen@gmail.com>
Co-authored-by: Nzhuangchong <zhuangchong6@163.com>
Co-authored-by: Nhailin0 <hailin0@yeah.net>
Co-authored-by: Nyangquan <iyeeku@qq.com>
Co-authored-by: syso1's avatarliliang1991 <liliang_68@126.com>
Co-authored-by: Nliang.li.c <liang.li.c@17zuoye.com>
Co-authored-by: Nfelix.wang <59079269+felix-thinkingdata@users.noreply.github.com>
Co-authored-by: Nchengshiwen <chengshiwen0103@gmail.com>
Co-authored-by: NYarlung <turingdojo@163.com>
Co-authored-by: Nkarlsun <karlsun@tencent.com>
Co-authored-by: Nwangxj3 <857234426@qq.com>
Co-authored-by: chengp...'s avatarchengp <5058557@qq.com>
Co-authored-by: Nchengp <chengp@chengp.net>
Co-authored-by: NSaksham Gupta <saksham1319@gmail.com>
Co-authored-by: NTq <36755957+Tianqi-Dotes@users.noreply.github.com>
Co-authored-by: NJatham <59549328+Jatham922@users.noreply.github.com>
Co-authored-by: Nhailin0 <hailin0@foxmail.com>
Co-authored-by: Nzh0122 <zh0122@gmail.com>
Co-authored-by: Ngeosmart <geosmart@hotmail.com>
Co-authored-by: 李丛阳's avatar李丛阳 <liby-1987@163.com>
Co-authored-by: N0002939 <licongyang@mininglamp.com>
Co-authored-by: kamisamak's avatarkamisamak <1057372918@qq.com>

* fix alert-spi error
todo sql script

* add page query plugin instance
add plugin instance check name

* add page query plugin instance
add plugin instance check name

* add props field

* ding talk some filed is not required

* fix bug

* fix error

* revert

* add name field provide to ui

* fix send error

* add ui

* delete useless constant definitions
code style

* code style

* fix license head error

* fix ut error

* fix ut error

* del unused jar

* import alert-plugin

* upgrade jboss-logging

* upgrade jboss-logging

* fix ut error

* fix Vulnerabilities

* fix Vulnerabilities

* fix Vulnerabilities

* code smell

* fix Vulnerabilities

* add  public constructors

* fix  Vulnerabilities

* resolve conflicts
Co-authored-by: Nbreak60 <790061044@qq.com>
Co-authored-by: Ngaojun2048 <32193458+gaojun2048@users.noreply.github.com>
Co-authored-by: Nzhuangchong <zhuangchong6@163.com>
Co-authored-by: Ndailidong <dailidong66@gmail.com>
Co-authored-by: 一子三木's avatarsamz406 <samz406@foxmail.com>
Co-authored-by: Ngaojun2048 <540957506@qq.com>
Co-authored-by: Nzhuangchong <37063904+zhuangchong@users.noreply.github.com>
Co-authored-by: NYichao Yang <1048262223@qq.com>
Co-authored-by: N小清 <62982788+597365581@users.noreply.github.com>
Co-authored-by: Nspring-bu <37682426+spring-bu@users.noreply.github.com>
Co-authored-by: Nlgcareer <18610854716@163.com>
Co-authored-by: NBoYiZhang <39816903+BoYiZhang@users.noreply.github.com>
Co-authored-by: Nxingchun-chen <55787491+xingchun-chen@users.noreply.github.com>
Co-authored-by: Nbaoliang <baoliang@analysys.com.cn>
Co-authored-by: NBoYiZhang <zhangboyi_mx@163.com>
Co-authored-by: _和's avatarzixi0825 <649790970@qq.com>
Co-authored-by: Nsunchaohe <sunzhaohe@linklogis.com>
Co-authored-by: Nbao liang <29528966+lenboo@users.noreply.github.com>
Co-authored-by: Nt1mon <178317391@qq.com>
Co-authored-by: Nzhanglong <zhanglong@ysstech.com>
Co-authored-by: N孙继峰 <sun.jifeng@outlook.com>
Co-authored-by: Nwulingqi <wulingqi@baijiahulian.com>
Co-authored-by: Nlgcareer <lgcareer@apache.org>
Co-authored-by: NIamMujuziMoses <49279842+IamMujuziMoses@users.noreply.github.com>
Co-authored-by: 愛吃枸杞的路星河's avatarhuzekang <1040080742@qq.com>
Co-authored-by: NJinyLeeChina <42576980+JinyLeeChina@users.noreply.github.com>
Co-authored-by: NEights-LI <yelli.eights@gmail.com>
Co-authored-by: Nwuchunfu <319355703@qq.com>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@analysys.com.cn>
Co-authored-by: NYelli <amarantine@my.com>
Co-authored-by: NEights-Li <yelli.hl@gmail.com>
Co-authored-by: Nqiaozhanwei <qiaozhanwei@outlook.com>
Co-authored-by: NXiaotaoYi <v-xiayi@hotmail.com>
Co-authored-by: Nzhuangchong <zhuangchong8@163.com>
Co-authored-by: Nmuzhongjiang <mu_zhongjiang@163.com>
Co-authored-by: NJave-Chen <baicai.chen@gmail.com>
Co-authored-by: Nhailin0 <hailin0@yeah.net>
Co-authored-by: Nyangquan <iyeeku@qq.com>
Co-authored-by: syso1's avatarliliang1991 <liliang_68@126.com>
Co-authored-by: Nliang.li.c <liang.li.c@17zuoye.com>
Co-authored-by: Nfelix.wang <59079269+felix-thinkingdata@users.noreply.github.com>
Co-authored-by: Nchengshiwen <chengshiwen0103@gmail.com>
Co-authored-by: NYarlung <turingdojo@163.com>
Co-authored-by: Nkarlsun <karlsun@tencent.com>
Co-authored-by: Nwangxj3 <857234426@qq.com>
Co-authored-by: chengp...'s avatarchengp <5058557@qq.com>
Co-authored-by: Nchengp <chengp@chengp.net>
Co-authored-by: NSaksham Gupta <saksham1319@gmail.com>
Co-authored-by: NTq <36755957+Tianqi-Dotes@users.noreply.github.com>
Co-authored-by: NJatham <59549328+Jatham922@users.noreply.github.com>
Co-authored-by: Nhailin0 <hailin0@foxmail.com>
Co-authored-by: Nzh0122 <zh0122@gmail.com>
Co-authored-by: Ngeosmart <geosmart@hotmail.com>
Co-authored-by: 李丛阳's avatar李丛阳 <liby-1987@163.com>
Co-authored-by: N0002939 <licongyang@mininglamp.com>
Co-authored-by: kamisamak's avatarkamisamak <1057372918@qq.com>
上级 43586da3
......@@ -216,3 +216,7 @@ The text of each license is the standard Apache 2.0 license.
ScriptRunner from https://github.com/mybatis/mybatis-3 Apache 2.0
mvnw files from https://github.com/takari/maven-wrapper Apache 2.0
PropertyPlaceholderHelper from https://github.com/spring-projects/spring-framework Apache 2.0
DolphinPluginClassLoader from https://github.com/prestosql/presto Apache 2.0
DolphinPluginDiscovery from https://github.com/prestosql/presto Apache 2.0
DolphinPluginLoader from https://github.com/prestosql/presto Apache 2.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.
#
dependencies:
- name: postgresql
version: 8.x.x
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: zookeeper
version: 5.x.x
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
\ No newline at end of file
#
# 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.
#
dependencies:
- name: postgresql
version: 8.x.x
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: zookeeper
version: 5.x.x
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
\ No newline at end of file
<?xml version="1.0" encoding="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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dolphinscheduler-alert-plugin</artifactId>
<groupId>org.apache.dolphinscheduler</groupId>
<version>1.3.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-alert-dingtalk</artifactId>
<packaging>dolphinscheduler-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>dolphinscheduler-alert-dingtalk-${project.version}</finalName>
</build>
</project>
\ No newline at end of file
/*
* 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.alert.dingtalk;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertData;
import org.apache.dolphinscheduler.spi.alert.AlertInfo;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer;
import java.util.Map;
/**
* DingTalkAlertChannel
*/
public class DingTalkAlertChannel implements AlertChannel {
@Override
public AlertResult process(AlertInfo alertInfo) {
AlertData alertData = alertInfo.getAlertData();
String alertParams = alertInfo.getAlertParams();
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams);
return new DingTalkSender(paramsMap).sendDingTalkMsg(alertData.getTitle(), alertData.getContent());
}
}
/*
* 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.alert.dingtalk;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import org.apache.dolphinscheduler.spi.params.InputParam;
import org.apache.dolphinscheduler.spi.params.PasswordParam;
import org.apache.dolphinscheduler.spi.params.RadioParam;
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.params.base.Validate;
import java.util.Arrays;
import java.util.List;
/**
* DingTalkAlertChannelFactory
*/
public class DingTalkAlertChannelFactory implements AlertChannelFactory {
@Override
public String getName() {
return "DingTalk";
}
@Override
public List<PluginParams> getParams() {
InputParam webHookParam = InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, DingTalkParamsConstants.DING_TALK_WEB_HOOK)
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam keywordParam = InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, DingTalkParamsConstants.DING_TALK_KEYWORD)
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
RadioParam isEnableProxy =
RadioParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE)
.addParamsOptions(new ParamsOptions("YES", true, false))
.addParamsOptions(new ParamsOptions("NO", false, false))
.setValue(true)
.addValidate(Validate.newBuilder()
.setRequired(false)
.build())
.build();
InputParam proxyParam =
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY, DingTalkParamsConstants.DING_TALK_PROXY)
.addValidate(Validate.newBuilder()
.setRequired(false).build())
.build();
InputParam portParam = InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PORT, DingTalkParamsConstants.DING_TALK_PORT)
.addValidate(Validate.newBuilder()
.setRequired(false).build())
.build();
InputParam userParam =
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_USER, DingTalkParamsConstants.DING_TALK_USER)
.addValidate(Validate.newBuilder()
.setRequired(false).build())
.build();
PasswordParam passwordParam = PasswordParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD, DingTalkParamsConstants.DING_TALK_PASSWORD)
.setPlaceholder("if enable use authentication, you need input password")
.build();
return Arrays.asList(webHookParam, keywordParam, isEnableProxy, proxyParam, portParam, userParam, passwordParam);
}
@Override
public AlertChannel create() {
return new DingTalkAlertChannel();
}
}
/*
* 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.alert.dingtalk;
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import com.google.common.collect.ImmutableList;
/**
* DingTalkAlertPlugin
*/
public class DingTalkAlertPlugin implements DolphinSchedulerPlugin {
@Override
public Iterable<AlertChannelFactory> getAlertChannelFactorys() {
return ImmutableList.of(new DingTalkAlertChannelFactory());
}
}
/*
* 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.alert.dingtalk;
/**
* DingTalkParamsConstants
*/
public class DingTalkParamsConstants {
public DingTalkParamsConstants() {
throw new IllegalStateException("Utility class");
}
static final String DING_TALK_WEB_HOOK = "dingtalk.webhook";
static final String NAME_DING_TALK_WEB_HOOK = "dingTalkWebHook";
static final String DING_TALK_KEYWORD = "dingtalk.keyword";
static final String NAME_DING_TALK_KEYWORD = "dingTalkKeyword";
public static final String DING_TALK_PROXY_ENABLE = "dingtalk.isEnableProxy";
static final String NAME_DING_TALK_PROXY_ENABLE = "dingTalkIsEnableProxy";
static final String DING_TALK_PROXY = "dingtalk.proxy";
static final String NAME_DING_TALK_PROXY = "dingTalkProxy";
static final String DING_TALK_PORT = "dingtalk.port";
static final String NAME_DING_TALK_PORT = "dingTalkPort";
static final String DING_TALK_USER = "dingtalk.user";
static final String NAME_DING_TALK_USER = "dingTalkUser";
static final String DING_TALK_PASSWORD = "dingtalk.password";
static final String NAME_DING_TALK_PASSWORD = "dingTalkPassword";
}
......@@ -15,9 +15,10 @@
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.utils;
package org.apache.dolphinscheduler.plugin.alert.dingtalk;
import org.apache.dolphinscheduler.common.utils.*;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.http.HttpEntity;
......@@ -42,43 +43,61 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* DingTalkUtils utils
* support send msg to ding talk by robot message push function.
* support PROXY setting
* Ding Talk Sender
*/
public class DingTalkUtils {
public static final Logger logger = LoggerFactory.getLogger(DingTalkUtils.class);
public static final boolean IS_ENABLE_DING_TALK = PropertyUtils.getBoolean(Constants.DINGTALK_ENABLE);
private static final String DING_TASK_URL = PropertyUtils.getString(Constants.DINGTALK_WEBHOOK);
private static final String KEYWORD = PropertyUtils.getString(Constants.DINGTALK_KEYWORD);
private static final Boolean IS_ENABLE_PROXY = PropertyUtils.getBoolean(Constants.DINGTALK_PROXY_ENABLE);
private static final String PROXY = PropertyUtils.getString(Constants.DINGTALK_PROXY);
private static final String USER = PropertyUtils.getString(Constants.DINGTALK_USER);
private static final String PASSWD = PropertyUtils.getString(Constants.DINGTALK_PASSWORD);
private static final Integer PORT = PropertyUtils.getInt(Constants.DINGTALK_PORT);
private DingTalkUtils() {
throw new IllegalStateException(DingTalkUtils.class.getName());
public class DingTalkSender {
private static final Logger logger = LoggerFactory.getLogger(DingTalkSender.class);
private String url;
private String keyword;
private Boolean enableProxy;
private String proxy;
private Integer port;
private String user;
private String password;
DingTalkSender(Map<String, String> config) {
url = config.get(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK);
keyword = config.get(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD);
enableProxy = Boolean.valueOf(config.get(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE));
if (Boolean.TRUE.equals(enableProxy)) {
port = Integer.parseInt(config.get(DingTalkParamsConstants.NAME_DING_TALK_PORT));
proxy = config.get(DingTalkParamsConstants.NAME_DING_TALK_PROXY);
user = config.get(DingTalkParamsConstants.DING_TALK_USER);
password = config.get(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD);
}
}
public AlertResult sendDingTalkMsg(String msg, String charset) {
AlertResult alertResult;
try {
String resp = sendMsg(msg, charset);
return checkSendDingTalkSendMsgResult(resp);
} catch (Exception e) {
logger.info("send ding talk alert msg exception : {}", e.getMessage());
alertResult = new AlertResult();
alertResult.setStatus("false");
alertResult.setMessage("send ding talk alert fail.");
}
return alertResult;
}
/**
* send message interface
* only support text message format now.
*
* @param msg message context to send
* @param charset charset type
* @return result of sending msg
* @throws IOException the IOException
*/
public static String sendDingTalkMsg(String msg, String charset) throws IOException {
String msgToJson = textToJsonString(msg + "#" + KEYWORD);
HttpPost httpPost = constructHttpPost(msgToJson, charset);
private String sendMsg(String msg, String charset) throws IOException {
String msgToJson = textToJsonString(msg + "#" + keyword);
HttpPost httpPost = constructHttpPost(url, msgToJson, charset);
CloseableHttpClient httpClient;
if (Boolean.TRUE.equals(IS_ENABLE_PROXY)) {
httpClient = getProxyClient();
RequestConfig rcf = getProxyConfig();
if (Boolean.TRUE.equals(enableProxy)) {
httpClient = getProxyClient(proxy, port, user, password);
RequestConfig rcf = getProxyConfig(proxy, port);
httpPost.setConfig(rcf);
} else {
httpClient = getDefaultClient();
......@@ -94,38 +113,38 @@ public class DingTalkUtils {
} finally {
response.close();
}
logger.info("Ding Talk send [{}], resp:{%s}", msg);
logger.info("Ding Talk send [ %s ], resp:{%s}", msg, resp);
return resp;
} finally {
httpClient.close();
}
}
public static HttpPost constructHttpPost(String msg, String charset) {
HttpPost post = new HttpPost(DING_TASK_URL);
private static HttpPost constructHttpPost(String url, String msg, String charset) {
HttpPost post = new HttpPost(url);
StringEntity entity = new StringEntity(msg, charset);
post.setEntity(entity);
post.addHeader("Content-Type", "application/json; charset=utf-8");
return post;
}
public static CloseableHttpClient getProxyClient() {
HttpHost httpProxy = new HttpHost(PROXY, PORT);
private static CloseableHttpClient getProxyClient(String proxy, int port, String user, String password) {
HttpHost httpProxy = new HttpHost(proxy, port);
CredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials(new AuthScope(httpProxy), new UsernamePasswordCredentials(USER, PASSWD));
provider.setCredentials(new AuthScope(httpProxy), new UsernamePasswordCredentials(user, password));
return HttpClients.custom().setDefaultCredentialsProvider(provider).build();
}
public static CloseableHttpClient getDefaultClient() {
private static CloseableHttpClient getDefaultClient() {
return HttpClients.createDefault();
}
public static RequestConfig getProxyConfig() {
HttpHost httpProxy = new HttpHost(PROXY, PORT);
private static RequestConfig getProxyConfig(String proxy, int port) {
HttpHost httpProxy = new HttpHost(proxy, port);
return RequestConfig.custom().setProxy(httpProxy).build();
}
public static String textToJsonString(String text) {
private static String textToJsonString(String text) {
Map<String, Object> items = new HashMap<>();
items.put("msgtype", "text");
Map<String, String> textContent = new HashMap<>();
......@@ -133,9 +152,53 @@ public class DingTalkUtils {
String txt = StringUtils.newStringUtf8(byt);
textContent.put("content", txt);
items.put("text", textContent);
return JSONUtils.toJsonString(items);
}
public static class DingTalkSendMsgResponse {
private Integer errcode;
private String errmsg;
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
private static AlertResult checkSendDingTalkSendMsgResult(String result) {
AlertResult alertResult = new AlertResult();
alertResult.setStatus("false");
if (null == result) {
alertResult.setMessage("send ding talk msg error");
logger.info("send ding talk msg error,ding talk server resp is null");
return alertResult;
}
DingTalkSendMsgResponse sendMsgResponse = JSONUtils.parseObject(result, DingTalkSendMsgResponse.class);
if (null == sendMsgResponse) {
alertResult.setMessage("send ding talk msg fail");
logger.info("send ding talk msg error,resp error");
return alertResult;
}
if (sendMsgResponse.errcode == 0) {
alertResult.setStatus("true");
alertResult.setMessage("send ding talk msg success");
return alertResult;
}
alertResult.setMessage(String.format("alert send ding talk msg error : %s", sendMsgResponse.getErrmsg()));
logger.info("alert send ding talk msg error : {}", sendMsgResponse.getErrmsg());
return alertResult;
}
}
/*
* 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.alert.dingtalk;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/**
* DingTalkAlertChannelFactoryTest
*/
public class DingTalkAlertChannelFactoryTest {
@Test
public void testGetParams() {
DingTalkAlertChannelFactory dingTalkAlertChannelFactory = new DingTalkAlertChannelFactory();
List<PluginParams> params = dingTalkAlertChannelFactory.getParams();
JSONUtils.toJsonString(params);
Assert.assertEquals(7, params.size());
}
@Test
public void testCreate() {
DingTalkAlertChannelFactory dingTalkAlertChannelFactory = new DingTalkAlertChannelFactory();
AlertChannel alertChannel = dingTalkAlertChannelFactory.create();
Assert.assertNotNull(alertChannel);
}
}
......@@ -14,59 +14,44 @@
* 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;
package org.apache.dolphinscheduler.plugin.alert.dingtalk;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class FilePluginManagerTest {
/**
* DingTalkSenderTest
*/
public class DingTalkSenderTest {
private FilePluginManager filePluginManager;
private AlertPlugin alertPlugin;
private static Map<String, String> dingTalkConfig = new HashMap<>();
@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()));
public void initDingTalkConfig() {
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, "keyWord");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, "url");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, "false");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD, "password");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PORT, "9988");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_USER, "user1,user2");
}
@Test
public void findAll() {
assertNotNull(filePluginManager.findAll());
public void testSend() {
DingTalkSender dingTalkSender = new DingTalkSender(dingTalkConfig);
dingTalkSender.sendDingTalkMsg("keyWord+Welcome", "UTF-8");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, "true");
dingTalkSender = new DingTalkSender(dingTalkConfig);
AlertResult alertResult = dingTalkSender.sendDingTalkMsg("keyWord+Welcome", "UTF-8");
Assert.assertEquals("false",alertResult.getStatus());
}
@Test
public void addPlugin() {
filePluginManager.addPlugin(alertPlugin);
assertNotNull(filePluginManager.findAll());
}
}
\ No newline at end of file
}
<?xml version="1.0" encoding="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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dolphinscheduler-alert-plugin</artifactId>
<groupId>org.apache.dolphinscheduler</groupId>
<version>1.3.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-alert-email</artifactId>
<!-- can be load as a Alert Plugin when development and run server in IDE -->
<packaging>dolphinscheduler-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>dolphinscheduler-alert-email-${project.version}</finalName>
</build>
</project>
\ No newline at end of file
/*
* 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.alert.email;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertData;
import org.apache.dolphinscheduler.spi.alert.AlertInfo;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* email alert channel . use email to seed the alertInfo
*/
public class EmailAlertChannel implements AlertChannel {
private static final Logger logger = LoggerFactory.getLogger(EmailAlertChannel.class);
@Override
public AlertResult process(AlertInfo info) {
AlertData alert = info.getAlertData();
String alertParams = info.getAlertParams();
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams);
MailSender mailSender = new MailSender(paramsMap);
AlertResult alertResult = mailSender.sendMails(alert.getTitle(), alert.getContent());
//send flag
boolean flag = false;
if (alertResult == null) {
alertResult = new AlertResult();
alertResult.setStatus("false");
alertResult.setMessage("alert send error.");
logger.info("alert send error : {}", alertResult.getMessage());
return alertResult;
}
flag = Boolean.parseBoolean(String.valueOf(alertResult.getStatus()));
if (flag) {
logger.info("alert send success");
alertResult.setMessage("email send success.");
} else {
alertResult.setMessage("alert send error.");
logger.info("alert send error : {}", alertResult.getMessage());
}
return alertResult;
}
}
/*
* 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.alert.email;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import org.apache.dolphinscheduler.spi.alert.AlertConstants;
import org.apache.dolphinscheduler.spi.alert.ShowType;
import org.apache.dolphinscheduler.spi.params.InputParam;
import org.apache.dolphinscheduler.spi.params.PasswordParam;
import org.apache.dolphinscheduler.spi.params.RadioParam;
import org.apache.dolphinscheduler.spi.params.base.DataType;
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.params.base.Validate;
import java.util.ArrayList;
import java.util.List;
/**
* email alert factory
*/
public class EmailAlertChannelFactory implements AlertChannelFactory {
@Override
public String getName() {
return "Email";
}
@Override
public List<PluginParams> getParams() {
List<PluginParams> paramsList = new ArrayList<>();
InputParam receivesParam = InputParam.newBuilder(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS, MailParamsConstants.PLUGIN_DEFAULT_EMAIL_RECEIVERS)
.setPlaceholder("please input receives")
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam receiveCcsParam = InputParam.newBuilder(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS, MailParamsConstants.PLUGIN_DEFAULT_EMAIL_RECEIVERCCS)
.build();
InputParam mailSmtpHost = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_HOST, MailParamsConstants.MAIL_SMTP_HOST)
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
InputParam mailSmtpPort = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_PORT, MailParamsConstants.MAIL_SMTP_PORT)
.setValue(25)
.addValidate(Validate.newBuilder()
.setRequired(true)
.setType(DataType.NUMBER.getDataType())
.build())
.build();
InputParam mailSender = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_SENDER, MailParamsConstants.MAIL_SENDER)
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
RadioParam enableSmtpAuth = RadioParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_AUTH, MailParamsConstants.MAIL_SMTP_AUTH)
.addParamsOptions(new ParamsOptions("YES", true, false))
.addParamsOptions(new ParamsOptions("NO", false, false))
.setValue(true)
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
InputParam mailUser = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_USER, MailParamsConstants.MAIL_USER)
.setPlaceholder("if enable use authentication, you need input user")
.build();
PasswordParam mailPassword = PasswordParam.newBuilder(MailParamsConstants.NAME_MAIL_PASSWD, MailParamsConstants.MAIL_PASSWD)
.setPlaceholder("if enable use authentication, you need input password")
.build();
RadioParam enableTls = RadioParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_STARTTLS_ENABLE, MailParamsConstants.MAIL_SMTP_STARTTLS_ENABLE)
.addParamsOptions(new ParamsOptions("YES", true, false))
.addParamsOptions(new ParamsOptions("NO", false, false))
.setValue(false)
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
RadioParam enableSsl = RadioParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_SSL_ENABLE, MailParamsConstants.MAIL_SMTP_SSL_ENABLE)
.addParamsOptions(new ParamsOptions("YES", true, false))
.addParamsOptions(new ParamsOptions("NO", false, false))
.setValue(false)
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
InputParam sslTrust = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_SSL_TRUST, MailParamsConstants.MAIL_SMTP_SSL_TRUST)
.setValue("*")
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
RadioParam showType = RadioParam.newBuilder(AlertConstants.SHOW_TYPE, AlertConstants.SHOW_TYPE)
.addParamsOptions(new ParamsOptions(ShowType.TABLE.getDescp(), ShowType.TABLE.getDescp(), false))
.addParamsOptions(new ParamsOptions(ShowType.TEXT.getDescp(), ShowType.TEXT.getDescp(), false))
.addParamsOptions(new ParamsOptions(ShowType.ATTACHMENT.getDescp(), ShowType.ATTACHMENT.getDescp(), false))
.addParamsOptions(new ParamsOptions(ShowType.TABLEATTACHMENT.getDescp(), ShowType.TABLEATTACHMENT.getDescp(), false))
.setValue(ShowType.TABLE.getDescp())
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
paramsList.add(receivesParam);
paramsList.add(receiveCcsParam);
paramsList.add(mailSmtpHost);
paramsList.add(mailSmtpPort);
paramsList.add(mailSender);
paramsList.add(enableSmtpAuth);
paramsList.add(mailUser);
paramsList.add(mailPassword);
paramsList.add(enableTls);
paramsList.add(enableSsl);
paramsList.add(sslTrust);
paramsList.add(showType);
return paramsList;
}
@Override
public AlertChannel create() {
return new EmailAlertChannel();
}
}
/*
* 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.alert.email;
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import com.google.common.collect.ImmutableList;
/**
* email alert plugin
*/
public class EmailAlertPlugin implements DolphinSchedulerPlugin {
@Override
public Iterable<AlertChannelFactory> getAlertChannelFactorys() {
return ImmutableList.of(new EmailAlertChannelFactory());
}
}
/*
* 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.alert.email;
public class EmailConstants {
public static final String XLS_FILE_PATH = "xls.file.path";
public static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol";
public static final String DEFAULT_SMTP_PORT = "25";
public static final String TEXT_HTML_CHARSET_UTF_8 = "text/html;charset=utf-8";
public static final int NUMBER_1000 = 1000;
public static final String TR = "<tr>";
public static final String TD = "<td>";
public static final String TD_END = "</td>";
public static final String TR_END = "</tr>";
public static final String TITLE = "title";
public static final String CONTENT = "content";
public static final String TH = "<th>";
public static final String TH_END = "</th>";
public static final String MARKDOWN_QUOTE = ">";
public static final String MARKDOWN_ENTER = "\n";
public static final String HTML_HEADER_PREFIX = new StringBuilder("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>")
.append("<html>")
.append("<head>")
.append("<title>dolphinscheduler</title>")
.append("<meta name='Keywords' content=''>")
.append("<meta name='Description' content=''>")
.append("<style type=\"text/css\">")
.append("table {margin-top:0px;padding-top:0px;border:1px solid;font-size: 14px;color: #333333;border-width: 1px;border-color: #666666;border-collapse: collapse;}")
.append("table th {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #dedede;text-align: left;}")
.append("table td {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #ffffff;text-align: left;}")
.append("</style>")
.append("</head>")
.append("<body style=\"margin:0;padding:0\"><table border=\"1px\" cellpadding=\"5px\" cellspacing=\"-10px\"> ")
.toString();
public static final String TABLE_BODY_HTML_TAIL = "</table></body></html>";
public static final String UTF_8 = "UTF-8";
public static final String EXCEL_SUFFIX_XLS = ".xls";
public static final String SINGLE_SLASH = "/";
}
......@@ -15,11 +15,11 @@
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.utils;
package org.apache.dolphinscheduler.plugin.alert.email;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
......@@ -31,6 +31,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
......@@ -43,12 +44,12 @@ import org.slf4j.LoggerFactory;
*/
public class ExcelUtils {
private static final Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
private ExcelUtils() {
throw new IllegalStateException(ExcelUtils.class.getName());
public ExcelUtils() {
throw new IllegalStateException("Utility class");
}
private static final Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
/**
* generate excel file
*
......@@ -71,7 +72,9 @@ public class ExcelUtils {
List<String> headerList = new ArrayList<>();
for (Map.Entry<String, Object> en : headerMap.entrySet()) {
Iterator<Map.Entry<String, Object>> iter = headerMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Object> en = iter.next();
headerList.add(en.getKey());
}
......@@ -122,11 +125,12 @@ public class ExcelUtils {
}
//setting file output
fos = new FileOutputStream(xlsFilePath + Constants.SINGLE_SLASH + title + Constants.EXCEL_SUFFIX_XLS);
fos = new FileOutputStream(xlsFilePath + EmailConstants.SINGLE_SLASH + title + EmailConstants.EXCEL_SUFFIX_XLS);
wb.write(fos);
} catch (Exception e) {
logger.error("generate excel error", e);
throw new RuntimeException("generate excel error", e);
} finally {
if (wb != null) {
......@@ -146,4 +150,4 @@ public class ExcelUtils {
}
}
}
}
\ No newline at end of file
/*
* 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.alert.email;
/**
* mail plugin params json use
*/
public class MailParamsConstants {
public MailParamsConstants() {
throw new IllegalStateException("Utility class");
}
public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERS = "$t('receivers')";
public static final String NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS = "receivers";
public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERCCS = "$t('receiverCcs')";
public static final String NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS = "receiverCcs";
public static final String MAIL_PROTOCOL = "transport.protocol";
public static final String NAME_MAIL_PROTOCOL = "protocol";
public static final String MAIL_SMTP_HOST = "smtp.host";
public static final String NAME_MAIL_SMTP_HOST = "serverHost";
public static final String MAIL_SMTP_PORT = "smtp.port";
public static final String NAME_MAIL_SMTP_PORT = "serverPort";
public static final String MAIL_SENDER = "sender";
public static final String NAME_MAIL_SENDER = "sender";
public static final String MAIL_SMTP_AUTH = "smtp.auth";
public static final String NAME_MAIL_SMTP_AUTH = "enableSmtpAuth";
public static final String MAIL_USER = "user";
public static final String NAME_MAIL_USER = "user";
public static final String MAIL_PASSWD = "passwd";
public static final String NAME_MAIL_PASSWD = "passwd";
public static final String MAIL_SMTP_STARTTLS_ENABLE = "smtp.starttls.enable";
public static final String NAME_MAIL_SMTP_STARTTLS_ENABLE = "starttlsEnable";
public static final String MAIL_SMTP_SSL_ENABLE = "smtp.ssl.enable";
public static final String NAME_MAIL_SMTP_SSL_ENABLE = "sslEnable";
public static final String MAIL_SMTP_SSL_TRUST = "smtp.ssl.trust";
public static final String NAME_MAIL_SMTP_SSL_TRUST = "smtpSslTrust";
}
......@@ -14,9 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.template;
import org.apache.dolphinscheduler.common.enums.ShowType;
package org.apache.dolphinscheduler.plugin.alert.email.template;
import org.apache.dolphinscheduler.spi.alert.ShowType;
/**
* alert message template
......@@ -25,20 +26,22 @@ public interface AlertTemplate {
/**
* get a message from a specified alert template
* @param content alert message content
* @param showType show type
* @param showAll whether to show all
*
* @param content alert message content
* @param showType show type
* @param showAll whether to show all
* @return a message from a specified alert template
*/
String getMessageFromTemplate(String content, ShowType showType,boolean showAll);
String getMessageFromTemplate(String content, ShowType showType, boolean showAll);
/**
* default showAll is true
* @param content alert message content
*
* @param content alert message content
* @param showType show type
* @return a message from a specified alert template
*/
default String getMessageFromTemplate(String content,ShowType showType){
return getMessageFromTemplate(content,showType,true);
default String getMessageFromTemplate(String content, ShowType showType) {
return getMessageFromTemplate(content, showType, true);
}
}
......@@ -15,21 +15,19 @@
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.template.impl;
package org.apache.dolphinscheduler.plugin.alert.email.template;
import static org.apache.dolphinscheduler.common.utils.Preconditions.checkNotNull;
import static java.util.Objects.requireNonNull;
import org.apache.dolphinscheduler.alert.template.AlertTemplate;
import org.apache.dolphinscheduler.alert.utils.Constants;
import org.apache.dolphinscheduler.common.enums.ShowType;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.plugin.alert.email.EmailConstants;
import org.apache.dolphinscheduler.spi.alert.ShowType;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import org.apache.dolphinscheduler.spi.utils.StringUtils;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.slf4j.Logger;
......@@ -52,7 +50,7 @@ public class DefaultHTMLTemplate implements AlertTemplate {
case TABLE:
return getTableTypeMessage(content, showAll);
case TEXT:
return getTextTypeMessage(content);
return getTextTypeMessage(content, showAll);
default:
throw new IllegalArgumentException(String.format("not support showType: %s in DefaultHTMLTemplate", showType));
}
......@@ -70,8 +68,8 @@ public class DefaultHTMLTemplate implements AlertTemplate {
if (StringUtils.isNotEmpty(content)) {
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class);
if (!showAll && mapItemsList.size() > Constants.NUMBER_1000) {
mapItemsList = mapItemsList.subList(0, Constants.NUMBER_1000);
if (!showAll && mapItemsList.size() > EmailConstants.NUMBER_1000) {
mapItemsList = mapItemsList.subList(0, EmailConstants.NUMBER_1000);
}
StringBuilder contents = new StringBuilder(200);
......@@ -81,21 +79,21 @@ public class DefaultHTMLTemplate implements AlertTemplate {
String title = "";
for (LinkedHashMap mapItems : mapItemsList) {
Set<Entry<String, Object>> entries = mapItems.entrySet();
Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
Iterator<Entry<String, Object>> iterator = entries.iterator();
Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
StringBuilder t = new StringBuilder(Constants.TR);
StringBuilder cs = new StringBuilder(Constants.TR);
StringBuilder t = new StringBuilder(EmailConstants.TR);
StringBuilder cs = new StringBuilder(EmailConstants.TR);
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
t.append(Constants.TH).append(entry.getKey()).append(Constants.TH_END);
cs.append(Constants.TD).append(String.valueOf(entry.getValue())).append(Constants.TD_END);
t.append(EmailConstants.TH).append(entry.getKey()).append(EmailConstants.TH_END);
cs.append(EmailConstants.TD).append(String.valueOf(entry.getValue())).append(EmailConstants.TD_END);
}
t.append(Constants.TR_END);
cs.append(Constants.TR_END);
t.append(EmailConstants.TR_END);
cs.append(EmailConstants.TR_END);
if (flag) {
title = t.toString();
}
......@@ -113,17 +111,18 @@ public class DefaultHTMLTemplate implements AlertTemplate {
* get alert message which type is TEXT
*
* @param content message content
* @param showAll weather to show all
* @return alert message
*/
private String getTextTypeMessage(String content) {
private String getTextTypeMessage(String content, boolean showAll) {
if (StringUtils.isNotEmpty(content)) {
ArrayNode list = JSONUtils.parseArray(content);
StringBuilder contents = new StringBuilder(100);
for (JsonNode jsonNode : list) {
contents.append(Constants.TR);
contents.append(Constants.TD).append(jsonNode.toString()).append(Constants.TD_END);
contents.append(Constants.TR_END);
contents.append(EmailConstants.TR);
contents.append(EmailConstants.TD).append(jsonNode.toString()).append(EmailConstants.TD_END);
contents.append(EmailConstants.TR_END);
}
return getMessageFromHtmlTemplate(null, contents.toString());
......@@ -136,16 +135,16 @@ public class DefaultHTMLTemplate implements AlertTemplate {
/**
* get alert message from a html template
*
* @param title message title
* @param title message title
* @param content message content
* @return alert message which use html template
*/
private String getMessageFromHtmlTemplate(String title, String content) {
checkNotNull(content);
String htmlTableThead = StringUtils.isEmpty(title) ? "" : String.format("<thead>%s</thead>%n", title);
requireNonNull(content, "content must not null");
String htmlTableThead = StringUtils.isEmpty(title) ? "" : String.format("<thead>%s</thead>\n", title);
return Constants.HTML_HEADER_PREFIX + htmlTableThead + content + Constants.TABLE_BODY_HTML_TAIL;
return EmailConstants.HTML_HEADER_PREFIX + htmlTableThead + content + EmailConstants.TABLE_BODY_HTML_TAIL;
}
}
......@@ -14,67 +14,62 @@
* 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.*;
package org.apache.dolphinscheduler.plugin.alert.email;
public class AlertDataTest {
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
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);
}
import java.util.List;
@Test
public void getId() {
assertEquals(1, alertData.getId());
}
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@Test
public void getTitle() {
assertEquals("title", alertData.getTitle());
}
/**
* EmailAlertChannelFactory Tester.
*
* @version 1.0
* @since <pre>Aug 20, 2020</pre>
*/
public class EmailAlertChannelFactoryTest {
@Test
public void getContent() {
assertEquals("content", alertData.getContent());
@Before
public void before() throws Exception {
}
@Test
public void getLog() {
assertEquals("log", alertData.getLog());
@After
public void after() throws Exception {
}
/**
* Method: getName()
*/
@Test
public void getAlertGroupId() {
assertEquals(1, alertData.getAlertGroupId());
public void testGetName() throws Exception {
}
/**
* Method: getParams()
*/
@Test
public void getReceivers() {
assertEquals("receivers", alertData.getReceivers());
public void testGetParams() throws Exception {
EmailAlertChannelFactory emailAlertChannelFactory = new EmailAlertChannelFactory();
List<PluginParams> params = emailAlertChannelFactory.getParams();
System.out.println(JSONUtils.toJsonString(params));
Assert.assertEquals(12, params.size());
}
/**
* Method: create()
*/
@Test
public void getReceiversCc() {
assertEquals("cc", alertData.getReceiversCc());
public void testCreate() throws Exception {
EmailAlertChannelFactory emailAlertChannelFactory = new EmailAlertChannelFactory();
AlertChannel alertChannel = emailAlertChannelFactory.create();
Assert.assertNotNull(alertChannel);
}
@Test
public void getShowType() {
assertEquals("email", alertData.getShowType());
}
}
\ No newline at end of file
}
/*
* 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.alert.email;
import org.apache.dolphinscheduler.spi.alert.AlertConstants;
import org.apache.dolphinscheduler.spi.alert.AlertData;
import org.apache.dolphinscheduler.spi.alert.AlertInfo;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.alert.ShowType;
import org.apache.dolphinscheduler.spi.params.InputParam;
import org.apache.dolphinscheduler.spi.params.PasswordParam;
import org.apache.dolphinscheduler.spi.params.RadioParam;
import org.apache.dolphinscheduler.spi.params.base.DataType;
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.params.base.Validate;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/**
* EmailAlertChannel Tester.
*/
public class EmailAlertChannelTest {
/**
* Method: process(AlertInfo info)
*/
@Test
public void testProcess() {
EmailAlertChannel emailAlertChannel = new EmailAlertChannel();
AlertData alertData = new AlertData();
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>();
map1.put("mysql service name", "mysql200");
map1.put("mysql address", "192.168.xx.xx");
map1.put("port", "3306");
map1.put("no index of number", "80");
map1.put("database client connections", "190");
List<LinkedHashMap<String, Object>> maps = new ArrayList<>();
maps.add(0, map1);
String mapjson = JSONUtils.toJsonString(maps);
alertData.setId(10)
.setContent(mapjson)
.setLog("10")
.setTitle("test");
AlertInfo alertInfo = new AlertInfo();
alertInfo.setAlertData(alertData);
alertInfo.setAlertParams(getEmailAlertParams());
AlertResult alertResult = emailAlertChannel.process(alertInfo);
Assert.assertNotNull(alertResult);
Assert.assertEquals("false", alertResult.getStatus());
}
public String getEmailAlertParams() {
List<PluginParams> paramsList = new ArrayList<>();
InputParam receivesParam = InputParam.newBuilder("receivers", "receivers")
.setValue("540957506@qq.com")
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
InputParam mailSmtpHost = InputParam.newBuilder("serverHost", "smtp.host")
.addValidate(Validate.newBuilder().setRequired(true).build())
.setValue("smtp.126.com")
.build();
InputParam mailSmtpPort = InputParam.newBuilder("serverPort", "smtp.port")
.addValidate(Validate.newBuilder()
.setRequired(true)
.setType(DataType.NUMBER.getDataType())
.build())
.setValue(25)
.build();
InputParam mailSender = InputParam.newBuilder("sender", "sender")
.addValidate(Validate.newBuilder().setRequired(true).build())
.setValue("dolphinscheduler@126.com")
.build();
RadioParam enableSmtpAuth = RadioParam.newBuilder("enableSmtpAuth", "smtp.auth")
.addParamsOptions(new ParamsOptions("YES", true, false))
.addParamsOptions(new ParamsOptions("NO", false, false))
.addValidate(Validate.newBuilder().setRequired(true).build())
.setValue(false)
.build();
InputParam mailUser = InputParam.newBuilder("user", "user")
.setPlaceholder("if enable use authentication, you need input user")
.setValue("dolphinscheduler@126.com")
.build();
PasswordParam mailPassword = PasswordParam.newBuilder("passwd", "passwd")
.setPlaceholder("if enable use authentication, you need input password")
.setValue("escheduler123")
.build();
RadioParam enableTls = RadioParam.newBuilder("starttlsEnable", "starttls.enable")
.addParamsOptions(new ParamsOptions("YES", true, false))
.addParamsOptions(new ParamsOptions("NO", false, false))
.addValidate(Validate.newBuilder().setRequired(true).build())
.setValue(true)
.build();
RadioParam enableSsl = RadioParam.newBuilder("sslEnable", "smtp.ssl.enable")
.addParamsOptions(new ParamsOptions("YES", true, false))
.addParamsOptions(new ParamsOptions("NO", false, false))
.addValidate(Validate.newBuilder().setRequired(true).build())
.setValue(true)
.build();
InputParam sslTrust = InputParam.newBuilder("smtpSslTrust", "smtp.ssl.trust")
.addValidate(Validate.newBuilder().setRequired(true).build())
.setValue("smtp.126.com")
.build();
List<ParamsOptions> emailShowTypeList = new ArrayList<>();
emailShowTypeList.add(new ParamsOptions(ShowType.TABLE.getDescp(), ShowType.TABLE.getDescp(), false));
emailShowTypeList.add(new ParamsOptions(ShowType.TEXT.getDescp(), ShowType.TEXT.getDescp(), false));
emailShowTypeList.add(new ParamsOptions(ShowType.ATTACHMENT.getDescp(), ShowType.ATTACHMENT.getDescp(), false));
emailShowTypeList.add(new ParamsOptions(ShowType.TABLEATTACHMENT.getDescp(), ShowType.TABLEATTACHMENT.getDescp(), false));
RadioParam showType = RadioParam.newBuilder(AlertConstants.SHOW_TYPE, "showType")
.setParamsOptionsList(emailShowTypeList)
.setValue(ShowType.TABLE.getDescp())
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
paramsList.add(receivesParam);
paramsList.add(mailSmtpHost);
paramsList.add(mailSmtpPort);
paramsList.add(mailSender);
paramsList.add(enableSmtpAuth);
paramsList.add(mailUser);
paramsList.add(mailPassword);
paramsList.add(enableTls);
paramsList.add(enableSsl);
paramsList.add(sslTrust);
paramsList.add(showType);
return JSONUtils.toJsonString(paramsList);
}
}
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.utils;
package org.apache.dolphinscheduler.plugin.alert.email;
import static org.junit.Assert.assertTrue;
......@@ -63,7 +63,7 @@ public class ExcelUtilsTest {
//Define dest file path
String xlsFilePath = rootPath + System.getProperty("file.separator");
logger.info("XLS_FILE_PATH: " + xlsFilePath);
logger.info("xlsFilePath: " + xlsFilePath);
//Define correctContent
String correctContent = "[{\"name\":\"ds name\",\"value\":\"ds value\"}]";
......@@ -78,7 +78,7 @@ public class ExcelUtilsTest {
ExcelUtils.genExcelFile(correctContent, title, xlsFilePath);
//Test file exists
File xlsFile = new File(xlsFilePath + Constants.SINGLE_SLASH + title + Constants.EXCEL_SUFFIX_XLS);
File xlsFile = new File(xlsFilePath + EmailConstants.SINGLE_SLASH + title + EmailConstants.EXCEL_SUFFIX_XLS);
assertTrue(xlsFile.exists());
//Expected RuntimeException
......@@ -98,7 +98,7 @@ public class ExcelUtilsTest {
@Test
public void testGenExcelFileByCheckDir() {
ExcelUtils.genExcelFile("[{\"a\": \"a\"},{\"a\": \"a\"}]", "t", "/tmp/xls");
File file = new File("/tmp/xls" + Constants.SINGLE_SLASH + "t" + Constants.EXCEL_SUFFIX_XLS);
File file = new File("/tmp/xls" + EmailConstants.SINGLE_SLASH + "t" + EmailConstants.EXCEL_SUFFIX_XLS);
file.delete();
}
}
}
\ No newline at end of file
/*
* 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.alert.email;
import org.apache.dolphinscheduler.plugin.alert.email.template.AlertTemplate;
import org.apache.dolphinscheduler.plugin.alert.email.template.DefaultHTMLTemplate;
import org.apache.dolphinscheduler.spi.alert.AlertConstants;
import org.apache.dolphinscheduler.spi.alert.ShowType;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*/
public class MailUtilsTest {
private static final Logger logger = LoggerFactory.getLogger(MailUtilsTest.class);
private static Map<String, String> emailConfig = new HashMap<>();
private static AlertTemplate alertTemplate;
static MailSender mailSender;
@BeforeClass
public static void initEmailConfig() {
emailConfig.put(MailParamsConstants.NAME_MAIL_PROTOCOL, "smtp");
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_HOST, "xxx.xxx.com");
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_PORT, "25");
emailConfig.put(MailParamsConstants.NAME_MAIL_SENDER, "xxx1.xxx.com");
emailConfig.put(MailParamsConstants.NAME_MAIL_USER, "xxx2.xxx.com");
emailConfig.put(MailParamsConstants.NAME_MAIL_PASSWD, "111111");
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_STARTTLS_ENABLE, "true");
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_SSL_ENABLE, "false");
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_SSL_TRUST, "false");
emailConfig.put(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS, "347801120@qq.com");
emailConfig.put(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS, "347801120@qq.com");
emailConfig.put(AlertConstants.SHOW_TYPE, ShowType.TEXT.getDescp());
alertTemplate = new DefaultHTMLTemplate();
mailSender = new MailSender(emailConfig);
}
@Test
public void testSendMails() {
String content = "[\"id:69\","
+ "\"name:UserBehavior-0--1193959466\","
+ "\"Job name: Start workflow\","
+ "\"State: SUCCESS\","
+ "\"Recovery:NO\","
+ "\"Run time: 1\","
+ "\"Start time: 2018-08-06 10:31:34.0\","
+ "\"End time: 2018-08-06 10:31:49.0\","
+ "\"Host: 192.168.xx.xx\","
+ "\"Notify group :4\"]";
mailSender.sendMails(
"Mysql Exception",
content);
}
public String list2String() {
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>();
map1.put("mysql service name", "mysql200");
map1.put("mysql address", "192.168.xx.xx");
map1.put("port", "3306");
map1.put("no index of number", "80");
map1.put("database client connections", "190");
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>();
map2.put("mysql service name", "mysql210");
map2.put("mysql address", "192.168.xx.xx");
map2.put("port", "3306");
map2.put("no index of number", "10");
map2.put("database client connections", "90");
List<LinkedHashMap<String, Object>> maps = new ArrayList<>();
maps.add(0, map1);
maps.add(1, map2);
String mapjson = JSONUtils.toJsonString(maps);
logger.info(mapjson);
return mapjson;
}
@Test
public void testSendTableMail() {
String title = "Mysql Exception";
String content = list2String();
emailConfig.put(AlertConstants.SHOW_TYPE, ShowType.TABLE.getDescp());
mailSender = new MailSender(emailConfig);
mailSender.sendMails(title, content);
}
@Test
public void testAttachmentFile() throws Exception {
String content = list2String();
emailConfig.put(AlertConstants.SHOW_TYPE, ShowType.ATTACHMENT.getDescp());
mailSender = new MailSender(emailConfig);
mailSender.sendMails("gaojing", content);
}
@Test
public void testTableAttachmentFile() throws Exception {
String content = list2String();
emailConfig.put(AlertConstants.SHOW_TYPE, ShowType.TABLEATTACHMENT.getDescp());
mailSender = new MailSender(emailConfig);
mailSender.sendMails("gaojing", content);
}
}
......@@ -14,25 +14,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.template.impl;
import org.apache.dolphinscheduler.common.utils.*;
import org.apache.dolphinscheduler.alert.utils.Constants;
import org.apache.dolphinscheduler.common.enums.ShowType;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
package org.apache.dolphinscheduler.plugin.alert.email.template;
import static org.junit.Assert.assertEquals;
import org.apache.dolphinscheduler.plugin.alert.email.EmailConstants;
import org.apache.dolphinscheduler.spi.alert.ShowType;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import static org.junit.Assert.*;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* test class for DefaultHTMLTemplate
*/
public class DefaultHTMLTemplateTest{
public class DefaultHTMLTemplateTest {
private static final Logger logger = LoggerFactory.getLogger(DefaultHTMLTemplateTest.class);
......@@ -40,57 +42,64 @@ public class DefaultHTMLTemplateTest{
* only need test method GetMessageFromTemplate
*/
@Test
public void testGetMessageFromTemplate(){
public void testGetMessageFromTemplate() {
DefaultHTMLTemplate template = new DefaultHTMLTemplate();
String tableTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TABLE,true);
String tableTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TABLE, true);
assertEquals(tableTypeMessage,generateMockTableTypeResultByHand());
assertEquals(tableTypeMessage, generateMockTableTypeResultByHand());
String textTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TEXT,true);
String textTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TEXT, true);
assertEquals(textTypeMessage,generateMockTextTypeResultByHand());
assertEquals(textTypeMessage, generateMockTextTypeResultByHand());
}
/**
* generate some simulation data
*/
private String list2String(){
private String list2String() {
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>();
map1.put("mysql service name","mysql200");
map1.put("mysql address","192.168.xx.xx");
map1.put("database client connections","190");
map1.put("port","3306");
map1.put("no index of number","80");
map1.put("mysql service name", "mysql200");
map1.put("mysql address", "192.168.xx.xx");
map1.put("database client connections", "190");
map1.put("port", "3306");
map1.put("no index of number", "80");
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>();
map2.put("mysql service name","mysql210");
map2.put("mysql address","192.168.xx.xx");
map2.put("database client connections","90");
map2.put("port","3306");
map2.put("no index of number","10");
map2.put("mysql service name", "mysql210");
map2.put("mysql address", "192.168.xx.xx");
map2.put("database client connections", "90");
map2.put("port", "3306");
map2.put("no index of number", "10");
List<LinkedHashMap<String, Object>> maps = new ArrayList<>();
maps.add(0,map1);
maps.add(1,map2);
maps.add(0, map1);
maps.add(1, map2);
String mapjson = JSONUtils.toJsonString(maps);
logger.info(mapjson);
return mapjson;
}
private String generateMockTableTypeResultByHand(){
private String generateMockTableTypeResultByHand() {
return Constants.HTML_HEADER_PREFIX +
"<thead><tr><th>mysql service name</th><th>mysql address</th><th>database client connections</th><th>port</th><th>no index of number</th></tr></thead>\n" +
"<tr><td>mysql200</td><td>192.168.xx.xx</td><td>190</td><td>3306</td><td>80</td></tr><tr><td>mysql210</td><td>192.168.xx.xx</td><td>90</td><td>3306</td><td>10</td></tr>" + Constants.TABLE_BODY_HTML_TAIL;
return EmailConstants.HTML_HEADER_PREFIX
+ "<thead>"
+ "<tr><th>mysql service name</th><th>mysql address</th><th>database client connections</th><th>port</th><th>no index of number</th></tr>"
+ "</thead>\n"
+ "<tr><td>mysql200</td><td>192.168.xx.xx</td><td>190</td><td>3306</td><td>80</td></tr>"
+ "<tr><td>mysql210</td><td>192.168.xx.xx</td><td>90</td><td>3306</td><td>10</td></tr>"
+ EmailConstants.TABLE_BODY_HTML_TAIL;
}
private String generateMockTextTypeResultByHand(){
private String generateMockTextTypeResultByHand() {
return Constants.HTML_HEADER_PREFIX + "<tr><td>{\"mysql service name\":\"mysql200\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"190\",\"port\":\"3306\",\"no index of number\":\"80\"}</td></tr><tr><td>{\"mysql service name\":\"mysql210\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"90\",\"port\":\"3306\",\"no index of number\":\"10\"}</td></tr>" + Constants.TABLE_BODY_HTML_TAIL;
return EmailConstants.HTML_HEADER_PREFIX
+ "<tr><td>{\"mysql service name\":\"mysql200\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"190\",\"port\":\"3306\",\"no index of number\":\"80\"}</td></tr>"
+ "<tr><td>{\"mysql service name\":\"mysql210\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"90\",\"port\":\"3306\",\"no index of number\":\"10\"}</td></tr>"
+ EmailConstants.TABLE_BODY_HTML_TAIL;
}
}
<?xml version="1.0" encoding="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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dolphinscheduler-alert-plugin</artifactId>
<groupId>org.apache.dolphinscheduler</groupId>
<version>1.3.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dolphinscheduler-alert-http</artifactId>
<packaging>dolphinscheduler-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>dolphinscheduler-alert-http-${project.version}</finalName>
</build>
</project>
\ No newline at end of file
/*
* 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.alert.http;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertData;
import org.apache.dolphinscheduler.spi.alert.AlertInfo;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer;
import java.util.Map;
/**
* http alert channel,use sms message to seed the alertInfo
*/
public class HttpAlertChannel implements AlertChannel {
@Override
public AlertResult process(AlertInfo alertInfo) {
AlertData alertData = alertInfo.getAlertData();
String alertParams = alertInfo.getAlertParams();
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams);
return new HttpSender(paramsMap).send(alertData.getContent());
}
}
/*
* 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.alert.http;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import org.apache.dolphinscheduler.spi.params.InputParam;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.params.base.Validate;
import java.util.Arrays;
import java.util.List;
/**
* http alert factory
*/
public class HttpAlertChannelFactory implements AlertChannelFactory {
@Override
public String getName() {
return "Http";
}
@Override
public List<PluginParams> getParams() {
InputParam url = InputParam.newBuilder(HttpAlertConstants.URL, HttpAlertConstants.URL)
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam headerParams = InputParam.newBuilder(HttpAlertConstants.HEADER_PARAMS, HttpAlertConstants.HEADER_PARAMS)
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam bodyParams = InputParam.newBuilder(HttpAlertConstants.BODY_PARAMS, HttpAlertConstants.BODY_PARAMS)
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam contentField = InputParam.newBuilder(HttpAlertConstants.CONTENT_FIELD, HttpAlertConstants.CONTENT_FIELD)
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam requestType = InputParam.newBuilder(HttpAlertConstants.REQUEST_TYPE, HttpAlertConstants.REQUEST_TYPE)
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
return Arrays.asList(url, requestType, headerParams, bodyParams, contentField);
}
@Override
public AlertChannel create() {
return new HttpAlertChannel();
}
}
/*
* 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.alert.http;
public class HttpAlertConstants {
private HttpAlertConstants() {
}
public static final String URL = "url";
public static final String HEADER_PARAMS = "headerParams";
public static final String BODY_PARAMS = "bodyParams";
public static final String CONTENT_FIELD = "contentField";
public static final String REQUEST_TYPE = "requestType";
}
/*
* 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.alert.http;
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import com.google.common.collect.ImmutableList;
/**
* http alertPlugins
*/
public class HttpAlertPlugin implements DolphinSchedulerPlugin {
@Override
public Iterable<AlertChannelFactory> getAlertChannelFactorys() {
return ImmutableList.of(new HttpAlertChannelFactory());
}
}
/*
* 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.alert.http;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import org.apache.dolphinscheduler.spi.utils.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* http send message
*/
public class HttpSender {
public static final Logger logger = LoggerFactory.getLogger(HttpSender.class);
private String url;
private final String headerParams;
private final String bodyParams;
private final String contentField;
private final String requestType;
private HttpRequestBase httpRequest;
private static final String URL_SPLICE_CHAR = "?";
/**
* request type post
*/
private static final String REQUEST_TYPE_POST = "POST";
/**
* request type get
*/
private static final String REQUEST_TYPE_GET = "GET";
private static final String DEFAULT_CHARSET = "utf-8";
public HttpSender(Map<String, String> paramsMap) {
url = paramsMap.get(HttpAlertConstants.URL);
headerParams = paramsMap.get(HttpAlertConstants.HEADER_PARAMS);
bodyParams = paramsMap.get(HttpAlertConstants.BODY_PARAMS);
contentField = paramsMap.get(HttpAlertConstants.CONTENT_FIELD);
requestType = paramsMap.get(HttpAlertConstants.REQUEST_TYPE);
}
public AlertResult send(String msg) {
AlertResult alertResult = new AlertResult();
createHttpRequest(msg);
if (httpRequest == null) {
alertResult.setStatus("false");
alertResult.setMessage("Request types are not supported");
return alertResult;
}
try {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse response = httpClient.execute(httpRequest);
HttpEntity entity = response.getEntity();
String resp = EntityUtils.toString(entity, DEFAULT_CHARSET);
alertResult.setStatus("true");
alertResult.setMessage(resp);
} catch (Exception e) {
logger.error("send http alert msg exception : {}", e.getMessage());
alertResult.setStatus("false");
alertResult.setMessage("send http request alert fail.");
}
return alertResult;
}
private void createHttpRequest(String msg) {
if (REQUEST_TYPE_POST.equals(requestType)) {
httpRequest = new HttpPost(url);
//POST request add param in request body
setMsgInRequestBody(msg);
} else if (REQUEST_TYPE_GET.equals(requestType)) {
//GET request add param in url
setMsgInUrl(msg);
httpRequest = new HttpGet(url);
}
setHeader();
}
/**
* add msg param in url
*/
private void setMsgInUrl(String msg) {
if (StringUtils.isNotBlank(contentField)) {
String type = "&";
//check splice char is & or ?
if (!url.contains(URL_SPLICE_CHAR)) {
type = URL_SPLICE_CHAR;
}
url = String.format("%s%s%s=%s", url, type, contentField, msg);
}
}
/**
* set header params
*/
private void setHeader() {
if (httpRequest == null) {
return;
}
HashMap<String, Object> map = JSONUtils.parseObject(headerParams, HashMap.class);
for (Map.Entry<String, Object> entry : map.entrySet()) {
httpRequest.setHeader(entry.getKey(), String.valueOf(entry.getValue()));
}
}
/**
* set body params
*/
private String setMsgInRequestBody(String msg) {
ObjectNode objectNode = JSONUtils.parseObject(bodyParams);
//set msg content field
objectNode.put(contentField, msg);
return objectNode.toString();
}
}
......@@ -14,41 +14,41 @@
* 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;
package org.apache.dolphinscheduler.plugin.alert.http;
import java.util.HashMap;
import java.util.Map;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import static org.junit.Assert.*;
import java.util.List;
public class AlertInfoTest {
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
private AlertInfo alertInfo;
/**
* HttpAlertChannelFactory UT
*/
public class HttpAlertChannelFactoryTest {
private HttpAlertChannelFactory httpAlertChannelFactory;
@Before
public void before() {
alertInfo = new AlertInfo();
public void init() {
httpAlertChannelFactory = new HttpAlertChannelFactory();
}
@Test
public void getAlertProps() {
Map<String, Object> map = new HashMap<>();
alertInfo.setAlertProps(map);
assertNotNull(alertInfo.getAlertProps());
}
public void getParamsTest() {
@Test
public void getProp() {
alertInfo.addProp("k", "v");
assertEquals("v", alertInfo.getProp("k"));
List<PluginParams> pluginParamsList = httpAlertChannelFactory.getParams();
Assert.assertEquals(5, pluginParamsList.size());
}
@Test
public void getAlertData() {
alertInfo.setAlertData(new AlertData());
assertNotNull(alertInfo.getAlertData());
public void createTest() {
AlertChannel alertChannel = httpAlertChannelFactory.create();
Assert.assertNotNull(alertChannel);
}
}
\ No newline at end of file
}
/*
* 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.alert.http;
import org.apache.dolphinscheduler.spi.alert.AlertData;
import org.apache.dolphinscheduler.spi.alert.AlertInfo;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.params.InputParam;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.params.base.Validate;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/**
* HttpAlertChannel UT
*/
public class HttpAlertChannelTest {
@Test
public void processTest() {
HttpAlertChannel alertChannel = new HttpAlertChannel();
AlertInfo alertInfo = new AlertInfo();
AlertData alertData = new AlertData();
alertData.setContent("Fault tolerance warning");
alertInfo.setAlertData(alertData);
AlertResult alertResult = alertChannel.process(alertInfo);
Assert.assertEquals("Request types are not supported", alertResult.getMessage());
}
@Test
public void processTest2() {
HttpAlertChannel alertChannel = new HttpAlertChannel();
AlertInfo alertInfo = new AlertInfo();
AlertData alertData = new AlertData();
alertData.setContent("Fault tolerance warning");
alertInfo.setAlertData(alertData);
alertInfo.setAlertParams(getParams());
AlertResult alertResult = alertChannel.process(alertInfo);
Assert.assertEquals("true", alertResult.getStatus());
}
/**
* create params
*/
private String getParams() {
List<PluginParams> paramsList = new ArrayList<>();
InputParam urlParam = InputParam.newBuilder("url", "url")
.setValue("http://www.baidu.com")
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
InputParam headerParams = InputParam.newBuilder("headerParams", "headerParams")
.addValidate(Validate.newBuilder().setRequired(true).build())
.setValue("{\"Content-Type\":\"application/json\"}")
.build();
InputParam bodyParams = InputParam.newBuilder("bodyParams", "bodyParams")
.addValidate(Validate.newBuilder().setRequired(true).build())
.setValue("{\"number\":\"13457654323\"}")
.build();
InputParam content = InputParam.newBuilder("contentField", "contentField")
.setValue("content")
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
InputParam requestType = InputParam.newBuilder("requestType", "requestType")
.setValue("POST")
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
paramsList.add(urlParam);
paramsList.add(headerParams);
paramsList.add(bodyParams);
paramsList.add(content);
paramsList.add(requestType);
return JSONUtils.toJsonString(paramsList);
}
}
/*
* 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.alert.http;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import org.junit.Assert;
import org.junit.Test;
/**
* HttpAlertPlugin UT
*/
public class HttpAlertPluginTest {
@Test
public void getAlertChannelFactorysTest() {
HttpAlertPlugin httpAlertPlugin = new HttpAlertPlugin();
Iterable<AlertChannelFactory> alertChannelFactorys = httpAlertPlugin.getAlertChannelFactorys();
Assert.assertNotNull(alertChannelFactorys);
}
}
/*
* 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.alert.http;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
/**
* HttpSender UT
*/
public class HttpSenderTest {
@Test
public void sendTest() {
Map<String, String> paramsMap = new HashMap<>();
paramsMap.put(HttpAlertConstants.URL, "http://www.baidu.com");
paramsMap.put(HttpAlertConstants.REQUEST_TYPE, "POST");
paramsMap.put(HttpAlertConstants.HEADER_PARAMS, "{\"Content-Type\":\"application/json\"}");
paramsMap.put(HttpAlertConstants.BODY_PARAMS, "{\"number\":\"13457654323\"}");
paramsMap.put(HttpAlertConstants.CONTENT_FIELD, "content");
HttpSender httpSender = new HttpSender(paramsMap);
AlertResult alertResult = httpSender.send("Fault tolerance warning");
Assert.assertEquals("true", alertResult.getStatus());
}
}
<?xml version="1.0" encoding="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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dolphinscheduler-alert-plugin</artifactId>
<groupId>org.apache.dolphinscheduler</groupId>
<version>1.3.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-alert-script</artifactId>
<packaging>dolphinscheduler-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>dolphinscheduler-alert-script-${project.version}</finalName>
</build>
</project>
\ No newline at end of file
/*
* 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.alert.script;
/**
* OSUtils
*/
public class OSUtils {
public OSUtils() {
throw new UnsupportedOperationException("Construct OSUtils");
}
static Boolean isWindows() {
return System.getProperty("os.name").startsWith("Windows");
}
}
......@@ -14,52 +14,49 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.template;
import org.apache.dolphinscheduler.alert.template.impl.DefaultHTMLTemplate;
import org.apache.dolphinscheduler.alert.utils.Constants;
import org.apache.dolphinscheduler.alert.utils.PropertyUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
package org.apache.dolphinscheduler.plugin.alert.script;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
/**
* test class for AlertTemplateFactory
* ProcessUtils
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest(PropertyUtils.class)
public class AlertTemplateFactoryTest {
public class ProcessUtils {
private static final Logger logger = LoggerFactory.getLogger(AlertTemplateFactoryTest.class);
private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
private ProcessUtils() {
throw new IllegalStateException("Utility class");
}
/**
* GetMessageTemplate method test
* executeScript
*
* @param cmd cmd params
* @return exit code
*/
@Test
public void testGetMessageTemplate(){
static Integer executeScript(String... cmd) {
PowerMockito.mockStatic(PropertyUtils.class);
int exitCode = -1;
AlertTemplate defaultTemplate = AlertTemplateFactory.getMessageTemplate();
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
try {
Process process = processBuilder.start();
StreamGobbler inputStreamGobbler = new StreamGobbler(process.getInputStream());
StreamGobbler errorStreamGobbler = new StreamGobbler(process.getErrorStream());
assertTrue(defaultTemplate instanceof DefaultHTMLTemplate);
}
/**
* GetMessageTemplate method throw Exception test
*/
@Test
public void testGetMessageTemplateException(){
inputStreamGobbler.start();
errorStreamGobbler.start();
return process.waitFor();
} catch (IOException | InterruptedException e) {
logger.error("execute alert script error {}", e.getMessage());
Thread.currentThread().interrupt();
}
AlertTemplate defaultTemplate = AlertTemplateFactory.getMessageTemplate();
assertTrue(defaultTemplate instanceof DefaultHTMLTemplate);
return exitCode;
}
}
/*
* 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.alert.script;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertData;
import org.apache.dolphinscheduler.spi.alert.AlertInfo;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer;
import java.util.Map;
/**
* ScriptAlertChannel
*/
public class ScriptAlertChannel implements AlertChannel {
@Override
public AlertResult process(AlertInfo alertinfo) {
AlertData alertData = alertinfo.getAlertData();
String alertParams = alertinfo.getAlertParams();
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams);
return new ScriptSender(paramsMap).sendScriptAlert(alertData.getTitle());
}
}
/*
* 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.alert.script;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import org.apache.dolphinscheduler.spi.params.InputParam;
import org.apache.dolphinscheduler.spi.params.RadioParam;
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.params.base.Validate;
import java.util.Arrays;
import java.util.List;
/**
* ScriptAlertChannelFactory
*/
public class ScriptAlertChannelFactory implements AlertChannelFactory {
@Override
public String getName() {
return "Script";
}
@Override
public List<PluginParams> getParams() {
InputParam scriptUserParam = InputParam.newBuilder(ScriptParamsConstants.NAME_SCRIPT_USER_PARAMS, ScriptParamsConstants.SCRIPT_USER_PARAMS)
.addValidate(Validate.newBuilder()
.setRequired(false)
.build())
.setPlaceholder("please enter your custom parameters, which will be passed to you when calling your script")
.build();
// need check file type and file exist
InputParam scriptPathParam = InputParam.newBuilder(ScriptParamsConstants.NAME_SCRIPT_PATH, ScriptParamsConstants.SCRIPT_PATH)
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.setPlaceholder("please upload the file to the disk directory of the alert server, and ensure that the path is absolute and has the corresponding access rights")
.build();
RadioParam scriptTypeParams = RadioParam.newBuilder(ScriptParamsConstants.NAME_SCRIPT_TYPE, ScriptParamsConstants.SCRIPT_TYPE)
.addParamsOptions(new ParamsOptions(ScriptType.SHELL.getDescp(), ScriptType.SHELL.getCode(), false))
.setValue(ScriptType.SHELL.getCode())
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
return Arrays.asList(scriptUserParam, scriptPathParam, scriptTypeParams);
}
@Override
public AlertChannel create() {
return new ScriptAlertChannel();
}
}
/*
* 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.alert.script;
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import com.google.common.collect.ImmutableList;
/**
* ScriptAlertPlugin
*/
public class ScriptAlertPlugin implements DolphinSchedulerPlugin {
@Override
public Iterable<AlertChannelFactory> getAlertChannelFactorys() {
return ImmutableList.of(new ScriptAlertChannelFactory());
}
}
/*
* 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.alert.script;
/**
* ScriptParamsConstants
*/
public class ScriptParamsConstants {
public ScriptParamsConstants() {
throw new IllegalStateException("Utility class");
}
static final String SCRIPT_TYPE = "type";
static final String NAME_SCRIPT_TYPE = "type";
static final String SCRIPT_PATH = "path";
static final String NAME_SCRIPT_PATH = "path";
static final String SCRIPT_USER_PARAMS = "user.params";
static final String NAME_SCRIPT_USER_PARAMS = "userParams";
}
/*
* 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.alert.script;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ScriptSender
*/
public class ScriptSender {
private static final Logger logger = LoggerFactory.getLogger(ScriptSender.class);
private String scriptPath;
private Integer scriptType;
private String userParams;
ScriptSender(Map<String, String> config) {
scriptPath = config.get(ScriptParamsConstants.NAME_SCRIPT_PATH);
scriptType = Integer.parseInt(config.get(ScriptParamsConstants.NAME_SCRIPT_TYPE));
userParams = config.get(ScriptParamsConstants.NAME_SCRIPT_USER_PARAMS);
}
AlertResult sendScriptAlert(String msg) {
AlertResult alertResult = new AlertResult();
if (ScriptType.of(scriptType).equals(ScriptType.SHELL)) {
return executeShellScript(msg);
}
return alertResult;
}
private AlertResult executeShellScript(String msg) {
AlertResult alertResult = new AlertResult();
alertResult.setStatus("false");
if (Boolean.TRUE.equals(OSUtils.isWindows())) {
alertResult.setMessage("shell script not support windows os");
return alertResult;
}
String[] cmd = {"/bin/sh", "-c", scriptPath + " " + msg + " " + userParams};
int exitCode = ProcessUtils.executeScript(cmd);
if (exitCode == 0) {
alertResult.setStatus("true");
alertResult.setMessage("send script alert msg success");
return alertResult;
}
alertResult.setMessage("send script alert msg error,exitCode is " + exitCode);
logger.info("send script alert msg error,exitCode is {}", exitCode);
return alertResult;
}
}
......@@ -14,48 +14,49 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.plugin.model;
package org.apache.dolphinscheduler.plugin.alert.script;
import java.util.HashMap;
import java.util.Map;
/**
* AlertInfo
* ScriptType
*/
public class AlertInfo {
public enum ScriptType {
private Map<String, Object> alertProps;
private AlertData alertData;
SHELL(0, "SHELL"),
;
public AlertInfo() {
this.alertProps = new HashMap<>();
ScriptType(int code, String descp) {
this.code = code;
this.descp = descp;
}
public Map<String, Object> getAlertProps() {
return alertProps;
}
private final int code;
private final String descp;
public AlertInfo setAlertProps(Map<String, Object> alertProps) {
this.alertProps = alertProps;
return this;
public int getCode() {
return code;
}
public AlertInfo addProp(String key, Object value) {
this.alertProps.put(key, value);
return this;
public String getDescp() {
return descp;
}
public Object getProp(String key) {
return this.alertProps.get(key);
}
private static final Map<Integer, ScriptType> SCRIPT_TYPE_MAP = new HashMap<>();
public AlertData getAlertData() {
return alertData;
static {
for (ScriptType scriptType : ScriptType.values()) {
SCRIPT_TYPE_MAP.put(scriptType.code, scriptType);
}
}
public AlertInfo setAlertData(AlertData alertData) {
this.alertData = alertData;
return this;
public static ScriptType of(Integer code) {
if (SCRIPT_TYPE_MAP.containsKey(code)) {
return SCRIPT_TYPE_MAP.get(code);
}
throw new IllegalArgumentException("invalid code : " + code);
}
}
......@@ -15,40 +15,47 @@
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.manager;
import org.apache.dolphinscheduler.alert.utils.Constants;
import org.apache.dolphinscheduler.alert.utils.DingTalkUtils;
import org.apache.dolphinscheduler.plugin.model.AlertInfo;
package org.apache.dolphinscheduler.plugin.alert.script;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Ding Talk Manager
* StreamGobbler
*/
public class DingTalkManager {
private static final Logger logger = LoggerFactory.getLogger(DingTalkManager.class);
public class StreamGobbler extends Thread {
private static final Logger logger = LoggerFactory.getLogger(StreamGobbler.class);
private InputStream inputStream;
StreamGobbler(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public void run() {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader inputBufferReader = new BufferedReader(inputStreamReader);
public Map<String, Object> send(AlertInfo alert) {
Map<String, Object> retMap = new HashMap<>();
retMap.put(Constants.STATUS, false);
logger.info("send message {}", alert.getAlertData().getTitle());
try {
String msg = buildMessage(alert);
DingTalkUtils.sendDingTalkMsg(msg, Constants.UTF_8);
String line;
StringBuilder output = new StringBuilder();
while ((line = inputBufferReader.readLine()) != null) {
output.append(line);
output.append(System.getProperty("line.separator"));
}
if (output.length() > 0) {
logger.info("out put msg is{}",output.toString());
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
logger.error("I/O error occurs {}", e.getMessage());
}
retMap.put(Constants.STATUS, true);
return retMap;
}
private String buildMessage(AlertInfo alert) {
return alert.getAlertData().getContent();
}
}
}
\ No newline at end of file
/*
* 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.alert.script;
import org.junit.Test;
/**
* ProcessUtilsTest
*/
public class ProcessUtilsTest {
private static final String rootPath = System.getProperty("user.dir");
private static final String shellFilPath = rootPath + "/dolphinscheduler-alert-plugin/dolphinscheduler-alert-script/src/test/script/shell/example.sh";
private String[] cmd = {"/bin/sh", "-c", shellFilPath + " " + "testMsg" + " " + "userParams"};
@Test
public void testExecuteScript() {
ProcessUtils.executeScript(cmd);
}
}
/*
* 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.alert.script;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/**
* ScriptAlertChannelFactoryTest
*/
public class ScriptAlertChannelFactoryTest {
@Test
public void testGetParams() {
ScriptAlertChannelFactory scriptAlertChannelFactory = new ScriptAlertChannelFactory();
List<PluginParams> params = scriptAlertChannelFactory.getParams();
JSONUtils.toJsonString(params);
Assert.assertEquals(3, params.size());
}
@Test
public void testCreate() {
ScriptAlertChannelFactory scriptAlertChannelFactory = new ScriptAlertChannelFactory();
AlertChannel alertChannel = scriptAlertChannelFactory.create();
Assert.assertNotNull(alertChannel);
}
}
/*
* 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.alert.script;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* ScriptSenderTest
*/
public class ScriptSenderTest {
private static Map<String, String> scriptConfig = new HashMap<>();
private static final String rootPath = System.getProperty("user.dir");
private static final String shellFilPath = rootPath + "/src/test/script/shell/scriptTest.sh";
@Before
public void initScriptConfig() {
scriptConfig.put(ScriptParamsConstants.NAME_SCRIPT_TYPE, String.valueOf(ScriptType.SHELL.getCode()));
scriptConfig.put(ScriptParamsConstants.NAME_SCRIPT_USER_PARAMS, "userParams");
scriptConfig.put(ScriptParamsConstants.NAME_SCRIPT_PATH, shellFilPath);
}
@Test
public void testScriptSenderTest() {
ScriptSender scriptSender = new ScriptSender(scriptConfig);
AlertResult alertResult;
alertResult = scriptSender.sendScriptAlert("success");
Assert.assertEquals("true", alertResult.getStatus());
alertResult = scriptSender.sendScriptAlert("errorMsg");
Assert.assertEquals("false", alertResult.getStatus());
}
}
#
# 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.
#
msg=$1
content=$2
# Write your specific logic here
# Set the exit code according to your execution result, and alert needs to use it to judge the status of this alarm result
exit 0
......@@ -15,8 +15,11 @@
# limitations under the License.
#
test.string=teststring
test.false=false
test.true=true
cba=3.1
test.long=100
\ No newline at end of file
msg=$1
content=$2
if [ $msg = errorMsg ]
then
exit 12
fi
exit 0
\ No newline at end of file
<?xml version="1.0" encoding="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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dolphinscheduler-alert-plugin</artifactId>
<groupId>org.apache.dolphinscheduler</groupId>
<version>1.3.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-alert-wechat</artifactId>
<packaging>dolphinscheduler-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>dolphinscheduler-alert-wechat-${project.version}</finalName>
</build>
</project>
\ No newline at end of file
/*
* 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.alert.wechat;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertData;
import org.apache.dolphinscheduler.spi.alert.AlertInfo;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer;
import java.util.Map;
/**
* WeChatAlertChannel
*/
public class WeChatAlertChannel implements AlertChannel {
@Override
public AlertResult process(AlertInfo info) {
AlertData alertData = info.getAlertData();
String alertParams = info.getAlertParams();
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams);
return new WeChatSender(paramsMap).sendEnterpriseWeChat(alertData.getTitle(), alertData.getContent());
}
}
/*
* 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.alert.wechat;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import org.apache.dolphinscheduler.spi.alert.AlertConstants;
import org.apache.dolphinscheduler.spi.alert.ShowType;
import org.apache.dolphinscheduler.spi.params.InputParam;
import org.apache.dolphinscheduler.spi.params.RadioParam;
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.params.base.Validate;
import java.util.Arrays;
import java.util.List;
/**
* WeChatAlertChannelFactory
*/
public class WeChatAlertChannelFactory implements AlertChannelFactory {
@Override
public String getName() {
return "WeChat";
}
@Override
public List<PluginParams> getParams() {
InputParam corpIdParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_CORP_ID)
.setPlaceholder("please input corp id ")
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam secretParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_SECRET)
.setPlaceholder("please input secret ")
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam usersParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USERS, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_USERS)
.setPlaceholder("please input users ")
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam userSendMsgParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_USER_SEND_MSG)
.setPlaceholder("please input corp id ")
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
InputParam agentIdParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_AGENT_ID, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_AGENT_ID)
.setPlaceholder("please input agent id ")
.addValidate(Validate.newBuilder()
.setRequired(true)
.build())
.build();
RadioParam showType = RadioParam.newBuilder(AlertConstants.SHOW_TYPE, AlertConstants.SHOW_TYPE)
.addParamsOptions(new ParamsOptions(ShowType.TABLE.getDescp(), ShowType.TABLE.getDescp(), false))
.addParamsOptions(new ParamsOptions(ShowType.TEXT.getDescp(), ShowType.TEXT.getDescp(), false))
.setValue(ShowType.TABLE.getDescp())
.addValidate(Validate.newBuilder().setRequired(true).build())
.build();
return Arrays.asList(corpIdParam, secretParam, usersParam, userSendMsgParam, agentIdParam, showType);
}
@Override
public AlertChannel create() {
return new WeChatAlertChannel();
}
}
/*
* 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.alert.wechat;
/**
* WeChatAlertConstants
*/
public class WeChatAlertConstants {
static final String MARKDOWN_QUOTE = ">";
static final String MARKDOWN_ENTER = "\n";
static final String CHARSET = "UTF-8";
static final String WE_CHAT_PUSH_URL = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}";
static final String WE_CHAT_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={secret}";
}
/*
* 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.alert.wechat;
/**
* WeChatAlertParamsConstants
*/
public class WeChatAlertParamsConstants {
static final String ENTERPRISE_WE_CHAT_CORP_ID = "corp.id";
static final String NAME_ENTERPRISE_WE_CHAT_CORP_ID = "corpId";
static final String ENTERPRISE_WE_CHAT_SECRET = "secret";
static final String NAME_ENTERPRISE_WE_CHAT_SECRET = "secret";
static final String ENTERPRISE_WE_CHAT_TEAM_SEND_MSG = "team.send.msg";
static final String NAME_ENTERPRISE_WE_CHAT_TEAM_SEND_MSG = "teamSendMsg";
static final String ENTERPRISE_WE_CHAT_USER_SEND_MSG = "user.send.msg";
static final String NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG = "userSendMsg";
static final String ENTERPRISE_WE_CHAT_AGENT_ID = "agent.id";
static final String NAME_ENTERPRISE_WE_CHAT_AGENT_ID = "agentId";
static final String ENTERPRISE_WE_CHAT_USERS = "users";
static final String NAME_ENTERPRISE_WE_CHAT_USERS = "users";
}
/*
* 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.alert.wechat;
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin;
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory;
import com.google.common.collect.ImmutableList;
/**
* WeChatAlertPlugin
*/
public class WeChatAlertPlugin implements DolphinSchedulerPlugin {
@Override
public Iterable<AlertChannelFactory> getAlertChannelFactorys() {
return ImmutableList.of(new WeChatAlertChannelFactory());
}
}
/*
* 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.alert.wechat;
import static java.util.Objects.requireNonNull;
import org.apache.dolphinscheduler.spi.alert.AlertConstants;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.alert.ShowType;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import org.apache.dolphinscheduler.spi.utils.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* WeChatSender
*/
public class WeChatSender {
private static Logger logger = LoggerFactory.getLogger(WeChatSender.class);
private String weChatAgentId;
private String weChatUsers;
private String weChatTeamSendMsg;
private String weChatUserSendMsg;
private String weChatTokenUrlReplace;
private String weChatToken;
private String showType;
private static final String agentIdRegExp = "{agentId}";
private static final String msgRegExp = "{msg}";
private static final String userRegExp = "{toUser}";
private static final String corpIdRegex = "{corpId}";
private static final String secretRegex = "{secret}";
private static final String toPartyRegex = "{toParty}";
private static final String toUserRegex = "{toUser}";
private static final String tokenRegex = "{token}";
WeChatSender(Map<String, String> config) {
weChatAgentId = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_AGENT_ID);
weChatUsers = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USERS);
String weChatCorpId = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID);
String weChatSecret = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET);
String weChatTokenUrl = WeChatAlertConstants.WE_CHAT_TOKEN_URL;
weChatTeamSendMsg = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_TEAM_SEND_MSG);
weChatUserSendMsg = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG);
showType = config.get(AlertConstants.SHOW_TYPE);
requireNonNull(showType, AlertConstants.SHOW_TYPE + " must not null");
weChatTokenUrlReplace = weChatTokenUrl
.replace(corpIdRegex, weChatCorpId)
.replace(secretRegex, weChatSecret);
weChatToken = getToken();
}
/**
* make user multi user message
*
* @param toUser the toUser
* @param agentId the agentId
* @param msg the msg
* @return Enterprise WeChat send message
*/
private String makeUserSendMsg(Collection<String> toUser, String agentId, String msg) {
String listUser = mkString(toUser);
return weChatUserSendMsg.replace(userRegExp, listUser)
.replace(agentIdRegExp, agentId)
.replace(msgRegExp, msg);
}
/**
* send Enterprise WeChat
*
* @return Enterprise WeChat resp, demo: {"errcode":0,"errmsg":"ok","invaliduser":""}
* @throws Exception the Exception
*/
public AlertResult sendEnterpriseWeChat(String title, String content) {
AlertResult alertResult;
List<String> userList = Arrays.asList(weChatUsers.split(","));
String data = markdownByAlert(title, content);
String msg = makeUserSendMsg(userList, weChatAgentId, data);
if (null == weChatToken) {
alertResult = new AlertResult();
alertResult.setMessage("send we chat alert fail,get weChat token error");
alertResult.setStatus("false");
return alertResult;
}
String enterpriseWeChatPushUrlReplace = WeChatAlertConstants.WE_CHAT_PUSH_URL.replace(tokenRegex, weChatToken);
try {
return checkWeChatSendMsgResult(post(enterpriseWeChatPushUrlReplace, msg));
} catch (Exception e) {
logger.info("send we chat alert msg exception : {}", e.getMessage());
alertResult = new AlertResult();
alertResult.setMessage("send we chat alert fail");
alertResult.setStatus("false");
}
return alertResult;
}
private static String post(String url, String data) throws IOException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(data, WeChatAlertConstants.CHARSET));
CloseableHttpResponse response = httpClient.execute(httpPost);
String resp;
try {
HttpEntity entity = response.getEntity();
resp = EntityUtils.toString(entity, WeChatAlertConstants.CHARSET);
EntityUtils.consume(entity);
} finally {
response.close();
}
logger.info("Enterprise WeChat send [{}], param:{}, resp:{}",
url, data, resp);
return resp;
}
}
/**
* convert table to markdown style
*
* @param title the title
* @param content the content
* @return markdown table content
*/
private static String markdownTable(String title, String content) {
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class);
if (null == mapItemsList || mapItemsList.isEmpty()) {
logger.error("itemsList is null");
throw new RuntimeException("itemsList is null");
}
StringBuilder contents = new StringBuilder(200);
for (LinkedHashMap mapItems : mapItemsList) {
Set<Entry<String, Object>> entries = mapItems.entrySet();
Iterator<Entry<String, Object>> iterator = entries.iterator();
StringBuilder t = new StringBuilder(String.format("`%s`%s", title, WeChatAlertConstants.MARKDOWN_ENTER));
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
t.append(WeChatAlertConstants.MARKDOWN_QUOTE);
t.append(entry.getKey()).append(":").append(entry.getValue());
t.append(WeChatAlertConstants.MARKDOWN_ENTER);
}
contents.append(t);
}
return contents.toString();
}
/**
* convert text to markdown style
*
* @param title the title
* @param content the content
* @return markdown text
*/
private static String markdownText(String title, String content) {
if (StringUtils.isNotEmpty(content)) {
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class);
if (null == mapItemsList || mapItemsList.isEmpty()) {
logger.error("itemsList is null");
throw new RuntimeException("itemsList is null");
}
StringBuilder contents = new StringBuilder(100);
contents.append(String.format("`%s`%n", title));
for (LinkedHashMap mapItems : mapItemsList) {
Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
for (Entry<String, Object> entry : entries) {
contents.append(WeChatAlertConstants.MARKDOWN_QUOTE);
contents.append(entry.getKey()).append(":").append(entry.getValue());
contents.append(WeChatAlertConstants.MARKDOWN_ENTER);
}
}
return contents.toString();
}
return null;
}
/**
* Determine the mardown style based on the show type of the alert
*
* @return the markdown alert table/text
*/
private String markdownByAlert(String title, String content) {
String result = "";
if (showType.equals(ShowType.TABLE.getDescp())) {
result = markdownTable(title, content);
} else if (showType.equals(ShowType.TEXT.getDescp())) {
result = markdownText(title, content);
}
return result;
}
private String getToken() {
try {
return get(weChatTokenUrlReplace);
} catch (IOException e) {
logger.info("we chat alert get token error{}", e.getMessage());
}
return null;
}
private static String get(String url) throws IOException {
String resp;
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet httpGet = new HttpGet(url);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
resp = EntityUtils.toString(entity, WeChatAlertConstants.CHARSET);
EntityUtils.consume(entity);
}
HashMap map = JSONUtils.parseObject(resp, HashMap.class);
if (map != null && null != map.get("access_token")) {
return map.get("access_token").toString();
} else {
return null;
}
}
}
private static String mkString(Iterable<String> list) {
if (null == list || StringUtils.isEmpty("|")) {
return null;
}
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String item : list) {
if (first) {
first = false;
} else {
sb.append("|");
}
sb.append(item);
}
return sb.toString();
}
public static class WeChatSendMsgResponse {
private Integer errcode;
private String errmsg;
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
private static AlertResult checkWeChatSendMsgResult(String result) {
AlertResult alertResult = new AlertResult();
alertResult.setStatus("false");
if (null == result) {
alertResult.setMessage("we chat send fail");
logger.info("send we chat msg error,resp is null");
return alertResult;
}
WeChatSendMsgResponse sendMsgResponse = JSONUtils.parseObject(result, WeChatSendMsgResponse.class);
if (null == sendMsgResponse) {
alertResult.setMessage("we chat send fail");
logger.info("send we chat msg error,resp error");
return alertResult;
}
if (sendMsgResponse.errcode == 0) {
alertResult.setStatus("true");
alertResult.setMessage("we chat alert send success");
return alertResult;
}
alertResult.setStatus("false");
alertResult.setMessage(sendMsgResponse.getErrmsg());
return alertResult;
}
}
/*
* 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.alert.wechat;
import org.apache.dolphinscheduler.spi.alert.AlertChannel;
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/**
* WeChatAlertChannelFactoryTest
*/
public class WeChatAlertChannelFactoryTest {
@Test
public void testGetParams() {
WeChatAlertChannelFactory weChatAlertChannelFactory = new WeChatAlertChannelFactory();
List<PluginParams> params = weChatAlertChannelFactory.getParams();
JSONUtils.toJsonString(params);
Assert.assertEquals(6, params.size());
}
@Test
public void testCreate() {
WeChatAlertChannelFactory dingTalkAlertChannelFactory = new WeChatAlertChannelFactory();
AlertChannel alertChannel = dingTalkAlertChannelFactory.create();
Assert.assertNotNull(alertChannel);
}
}
/*
* 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.alert.wechat;
import org.apache.dolphinscheduler.spi.alert.AlertConstants;
import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.alert.ShowType;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* WeChatSenderTest
*/
public class WeChatSenderTest {
private static Map<String, String> weChatConfig = new HashMap<>();
private String content = "[{\"id\":\"69\","
+
"\"name\":\"UserBehavior-0--1193959466\","
+
"\"Job name\":\"Start workflow\","
+
"\"State\":\"SUCCESS\","
+
"\"Recovery\":\"NO\","
+
"\"Run time\":\"1\","
+
"\"Start time\": \"2018-08-06 10:31:34.0\","
+
"\"End time\": \"2018-08-06 10:31:49.0\","
+
"\"Host\": \"192.168.xx.xx\","
+
"\"Notify group\" :\"4\"}]";
@Before
public void initDingTalkConfig() {
// Just for this test, I will delete these configurations before this PR is merged
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_AGENT_ID, "100000");
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID, "NAME_ENTERPRISE_WE_CHAT_CORP_ID");
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET, "NAME_ENTERPRISE_WE_CHAT_SECRET");
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG, "{\"touser\":\"{toUser}\",\"agentid\":{agentId}"
+
",\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"{msg}\"}}"
);
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USERS, "Kris");
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_TEAM_SEND_MSG, "msg");
weChatConfig.put(AlertConstants.SHOW_TYPE, ShowType.TABLE.getDescp());
}
@Test
public void testSendWeChatTableMsg() {
WeChatSender weChatSender = new WeChatSender(weChatConfig);
AlertResult alertResult = weChatSender.sendEnterpriseWeChat("test", content);
Assert.assertEquals("false", alertResult.getStatus());
}
@Test
public void testSendWeChatTextMsg() {
weChatConfig.put(AlertConstants.SHOW_TYPE, ShowType.TEXT.getDescp());
WeChatSender weChatSender = new WeChatSender(weChatConfig);
AlertResult alertResult = weChatSender.sendEnterpriseWeChat("test", content);
Assert.assertEquals("false", alertResult.getStatus());
}
}
<?xml version="1.0" encoding="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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dolphinscheduler</artifactId>
<groupId>org.apache.dolphinscheduler</groupId>
<version>1.3.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-alert-plugin</artifactId>
<packaging>pom</packaging>
<modules>
<module>dolphinscheduler-alert-email</module>
<module>dolphinscheduler-alert-wechat</module>
<module>dolphinscheduler-alert-dingtalk</module>
<module>dolphinscheduler-alert-script</module>
<module>dolphinscheduler-alert-http</module>
</modules>
</project>
\ No newline at end of file
......@@ -32,38 +32,21 @@
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-spi</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<type>jar</type>
<scope>test</scope>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-remote</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<scope>test</scope>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-common</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
</dependency>
<dependency>
......@@ -108,6 +91,52 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.airlift.resolver</groupId>
<artifactId>resolver</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.alert.manager;
import org.apache.dolphinscheduler.alert.utils.MailUtils;
import java.util.List;
import java.util.Map;
/**
* email send manager
*/
public class EmailManager {
/**
* email send
* @param receiversList the receiver list
* @param receiversCcList the cc List
* @param title the title
* @param content the content
* @param showType the showType
* @return the send result
*/
public Map<String,Object> send(List<String> receiversList,List<String> receiversCcList,String title,String content,String showType){
return MailUtils.sendMails(receiversList, receiversCcList, title, content, showType);
}
/**
* msg send
* @param receiversList the receiver list
* @param title the title
* @param content the content
* @param showType the showType
* @return the send result
*/
public Map<String,Object> send(List<String> receiversList,String title,String content,String showType){
return MailUtils.sendMails(receiversList,title, content, showType);
}
}
///*
// * Licensed to the Apache Software Foundation (ASF) under one or more
// * contributor license agreements. See the NOTICE file distributed with
// * this work for additional information regarding copyright ownership.
// * The ASF licenses this file to You under the Apache License, Version 2.0
// * (the "License"); you may not use this file except in compliance with
// * the License. You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//package org.apache.dolphinscheduler.alert.manager;
//
//import org.apache.dolphinscheduler.alert.utils.MailUtils;
//
//import java.util.List;
//import java.util.Map;
//
///**
// * email send manager
// */
//public class EmailManager {
// /**
// * email send
// * @param receiversList the receiver list
// * @param receiversCcList the cc List
// * @param title the title
// * @param content the content
// * @param showType the showType
// * @return the send result
// */
// public Map<String,Object> send(List<String> receiversList,List<String> receiversCcList,String title,String content,String showType){
//
// return MailUtils.sendMails(receiversList, receiversCcList, title, content, showType);
// }
//
// /**
// * msg send
// * @param receiversList the receiver list
// * @param title the title
// * @param content the content
// * @param showType the showType
// * @return the send result
// */
// public Map<String,Object> send(List<String> receiversList,String title,String content,String showType){
//
// return MailUtils.sendMails(receiversList,title, content, showType);
// }
//
//}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册