You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ca...@apache.org on 2022/01/12 10:14:01 UTC
[dolphinscheduler] branch 2.0.3-prepare updated: cherry-pick DingTalk alert plugin adds signature. #7805 (#7959)
This is an automated email from the ASF dual-hosted git repository.
caishunfeng pushed a commit to branch 2.0.3-prepare
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/2.0.3-prepare by this push:
new 7b1744b cherry-pick DingTalk alert plugin adds signature. #7805 (#7959)
7b1744b is described below
commit 7b1744baf505e4b1a8f5737f0a4cd1fa6286c10c
Author: Kerwin <37...@users.noreply.github.com>
AuthorDate: Wed Jan 12 18:13:55 2022 +0800
cherry-pick DingTalk alert plugin adds signature. #7805 (#7959)
---
.../dingtalk/DingTalkAlertChannelFactory.java | 68 +++++++++++++---------
.../alert/dingtalk/DingTalkParamsConstants.java | 8 ++-
.../plugin/alert/dingtalk/DingTalkSender.java | 57 +++++++++++++++---
.../dingtalk/DingTalkAlertChannelFactoryTest.java | 2 +-
.../src/js/module/i18n/locale/en_US.js | 1 +
.../src/js/module/i18n/locale/zh_CN.js | 3 +-
6 files changed, 102 insertions(+), 37 deletions(-)
diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java
index 2050eaa..01b9060 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java
+++ b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java
@@ -50,46 +50,62 @@ public final class DingTalkAlertChannelFactory implements AlertChannelFactory {
@Override
public List<PluginParams> params() {
- InputParam webHookParam = InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, DingTalkParamsConstants.DING_TALK_WEB_HOOK)
+
+ 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)
+
+ InputParam keywordParam = InputParam
+ .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, DingTalkParamsConstants.DING_TALK_KEYWORD)
.addValidate(Validate.newBuilder()
- .setRequired(true)
+ .setRequired(false)
.build())
.build();
- RadioParam isEnableProxy =
- RadioParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE)
- .addParamsOptions(new ParamsOptions(STRING_YES, STRING_TRUE, false))
- .addParamsOptions(new ParamsOptions(STRING_NO, STRING_FALSE, false))
- .setValue(STRING_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)
+ InputParam secretParam = InputParam
+ .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_SECRET, DingTalkParamsConstants.DING_TALK_SECRET)
.addValidate(Validate.newBuilder()
- .setRequired(false).build())
+ .setRequired(false)
+ .build())
+ .build();
+ RadioParam isEnableProxy = RadioParam
+ .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, DingTalkParamsConstants.DING_TALK_PROXY_ENABLE)
+ .addParamsOptions(new ParamsOptions(STRING_YES, STRING_TRUE, false))
+ .addParamsOptions(new ParamsOptions(STRING_NO, STRING_FALSE, false))
+ .setValue(STRING_FALSE)
+ .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)
+ 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);
+ return Arrays.asList(webHookParam, keywordParam, secretParam, isEnableProxy, proxyParam, portParam, userParam, passwordParam);
}
}
diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
index 3042db6..fa47b0c 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
+++ b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
@@ -18,12 +18,18 @@
package org.apache.dolphinscheduler.plugin.alert.dingtalk;
public final class DingTalkParamsConstants {
+
static final String DING_TALK_PROXY_ENABLE = "isEnableProxy";
+ static final String NAME_DING_TALK_PROXY_ENABLE = "IsEnableProxy";
+
static final String DING_TALK_WEB_HOOK = "webhook";
static final String NAME_DING_TALK_WEB_HOOK = "WebHook";
static final String DING_TALK_KEYWORD = "keyword";
static final String NAME_DING_TALK_KEYWORD = "Keyword";
- static final String NAME_DING_TALK_PROXY_ENABLE = "IsEnableProxy";
+
+ static final String DING_TALK_SECRET = "secret";
+ static final String NAME_DING_TALK_SECRET = "Secret";
+
static final String DING_TALK_PROXY = "proxy";
static final String NAME_DING_TALK_PROXY = "Proxy";
static final String DING_TALK_PORT = "port";
diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
index f5d5f14..eeca8c0 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
+++ b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
@@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.plugin.alert.dingtalk;
import org.apache.dolphinscheduler.alert.api.AlertResult;
import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
@@ -36,16 +37,30 @@ import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
+import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+/**
+ * <p>
+ * https://open.dingtalk.com/document/robots/custom-robot-access
+ * https://open.dingtalk.com/document/robots/customize-robot-security-settings
+ * </p>
+ */
public final class DingTalkSender {
- private static final Logger log = org.slf4j.LoggerFactory.getLogger(DingTalkSender.class);
+
+ private static final Logger logger = LoggerFactory.getLogger(DingTalkSender.class);
+
private final String url;
private final String keyword;
+ private final String secret;
private final Boolean enableProxy;
private String proxy;
@@ -59,6 +74,7 @@ public final class DingTalkSender {
DingTalkSender(Map<String, String> config) {
url = config.get(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK);
keyword = config.get(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD);
+ secret = config.get(DingTalkParamsConstants.NAME_DING_TALK_SECRET);
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));
@@ -109,13 +125,13 @@ public final class DingTalkSender {
if (null == result) {
alertResult.setMessage("send ding talk msg error");
- log.info("send ding talk msg error,ding talk server resp is null");
+ 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");
- log.info("send ding talk msg error,resp error");
+ logger.info("send ding talk msg error,resp error");
return alertResult;
}
if (sendMsgResponse.errcode == 0) {
@@ -124,7 +140,7 @@ public final class DingTalkSender {
return alertResult;
}
alertResult.setMessage(String.format("alert send ding talk msg error : %s", sendMsgResponse.getErrmsg()));
- log.info("alert send ding talk msg error : {}", sendMsgResponse.getErrmsg());
+ logger.info("alert send ding talk msg error : {}", sendMsgResponse.getErrmsg());
return alertResult;
}
@@ -134,7 +150,7 @@ public final class DingTalkSender {
String resp = sendMsg(title, content);
return checkSendDingTalkSendMsgResult(resp);
} catch (Exception e) {
- log.info("send ding talk alert msg exception : {}", e.getMessage());
+ logger.info("send ding talk alert msg exception : {}", e.getMessage());
alertResult = new AlertResult();
alertResult.setStatus("false");
alertResult.setMessage("send ding talk alert fail.");
@@ -144,8 +160,18 @@ public final class DingTalkSender {
private String sendMsg(String title, String content) throws IOException {
- String msgToJson = textToJsonString(title + content + "#" + keyword);
- HttpPost httpPost = constructHttpPost(url, msgToJson);
+ StringBuilder text = new StringBuilder();
+ if (org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(keyword)) {
+ text.append(keyword);
+ text.append(":");
+ }
+ text.append(title);
+ text.append("\n");
+ text.append(content);
+
+ String msgToJson = textToJsonString(text.toString());
+
+ HttpPost httpPost = constructHttpPost(org.apache.dolphinscheduler.spi.utils.StringUtils.isBlank(secret) ? url : generateSignedUrl(), msgToJson);
CloseableHttpClient httpClient;
if (Boolean.TRUE.equals(enableProxy)) {
@@ -166,13 +192,28 @@ public final class DingTalkSender {
} finally {
response.close();
}
- log.info("Ding Talk send title :{},content : {}, resp: {}", title, content, resp);
+ logger.info("Ding Talk send title :{},content : {}, resp: {}", title, content, resp);
return resp;
} finally {
httpClient.close();
}
}
+ private String generateSignedUrl() {
+ Long timestamp = System.currentTimeMillis();
+ String stringToSign = timestamp + "\n" + secret;
+ String sign = org.apache.dolphinscheduler.spi.utils.StringUtils.EMPTY;
+ try {
+ Mac mac = Mac.getInstance("HmacSHA256");
+ mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
+ byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
+ sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)),"UTF-8");
+ } catch (Exception e) {
+ logger.error("generate sign error, message:{}", e);
+ }
+ return url + "×tamp=" + timestamp + "&sign=" + sign;
+ }
+
static final class DingTalkSendMsgResponse {
private Integer errcode;
private String errmsg;
diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java
index 8b78042..9905195 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java
+++ b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java
@@ -32,7 +32,7 @@ public class DingTalkAlertChannelFactoryTest {
DingTalkAlertChannelFactory dingTalkAlertChannelFactory = new DingTalkAlertChannelFactory();
List<PluginParams> params = dingTalkAlertChannelFactory.params();
JSONUtils.toJsonString(params);
- Assert.assertEquals(7, params.size());
+ Assert.assertEquals(8, params.size());
}
@Test
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
index e7abaf6..c749142 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
@@ -726,6 +726,7 @@ export default {
WebHook: 'WebHook',
webHook: 'WebHook',
Keyword: 'Keyword',
+ Secret: 'Secret',
Proxy: 'Proxy',
receivers: 'Receivers',
receiverCcs: 'ReceiverCcs',
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
index 70a71f1..4d62bb9 100644
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
@@ -724,7 +724,8 @@ export default {
IsEnableProxy: '启用代理',
WebHook: 'Web钩子',
webHook: 'Web钩子',
- Keyword: '密钥',
+ Keyword: '关键词',
+ Secret: '密钥',
Proxy: '代理',
receivers: '收件人',
receiverCcs: '抄送人',