Browse Source

[Improvement-8284][Alert] Dingtalk alert plugin supports markdown message type (#8285)

* add msgtype in the dingtalk alert plugin

* update markdown msgtype 'at persion'
3.0.0/version-upgrade
Kerwin 3 years ago committed by GitHub
parent
commit
36d526d3a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java
  2. 6
      dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
  3. 162
      dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
  4. 2
      dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java
  5. 4
      dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSenderTest.java
  6. 1
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  7. 1
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

13
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java

@ -64,6 +64,17 @@ public final class DingTalkAlertChannelFactory implements AlertChannelFactory {
.setRequired(false) .setRequired(false)
.build()) .build())
.build(); .build();
RadioParam msgTypeParam = RadioParam
.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_MSG_TYPE, DingTalkParamsConstants.DING_TALK_MSG_TYPE)
.addParamsOptions(new ParamsOptions(DingTalkParamsConstants.DING_TALK_MSG_TYPE_TEXT, DingTalkParamsConstants.DING_TALK_MSG_TYPE_TEXT, false))
.addParamsOptions(new ParamsOptions(DingTalkParamsConstants.DING_TALK_MSG_TYPE_MARKDOWN, DingTalkParamsConstants.DING_TALK_MSG_TYPE_MARKDOWN, false))
.setValue(DingTalkParamsConstants.DING_TALK_MSG_TYPE_TEXT)
.addValidate(Validate.newBuilder()
.setRequired(false)
.build())
.build();
InputParam atMobilesParam = InputParam InputParam atMobilesParam = InputParam
.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_AT_MOBILES, DingTalkParamsConstants.DING_TALK_AT_MOBILES) .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_AT_MOBILES, DingTalkParamsConstants.DING_TALK_AT_MOBILES)
.addValidate(Validate.newBuilder() .addValidate(Validate.newBuilder()
@ -120,7 +131,7 @@ public final class DingTalkAlertChannelFactory implements AlertChannelFactory {
.setPlaceholder("if enable use authentication, you need input password") .setPlaceholder("if enable use authentication, you need input password")
.build(); .build();
return Arrays.asList(webHookParam, keywordParam, secretParam, atMobilesParam, atUserIdsParam, isAtAll, isEnableProxy, proxyParam, portParam, userParam, passwordParam); return Arrays.asList(webHookParam, keywordParam, secretParam, msgTypeParam, atMobilesParam, atUserIdsParam, isAtAll, isEnableProxy, proxyParam, portParam, userParam, passwordParam);
} }
@Override @Override

6
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java

@ -30,6 +30,12 @@ public final class DingTalkParamsConstants {
static final String DING_TALK_SECRET = "$t('secret')"; static final String DING_TALK_SECRET = "$t('secret')";
static final String NAME_DING_TALK_SECRET = "Secret"; static final String NAME_DING_TALK_SECRET = "Secret";
static final String DING_TALK_MSG_TYPE = "$t('msgType')";
static final String NAME_DING_TALK_MSG_TYPE = "MsgType";
static final String DING_TALK_MSG_TYPE_TEXT = "text";
static final String DING_TALK_MSG_TYPE_MARKDOWN = "markdown";
static final String DING_TALK_AT_MOBILES = "$t('atMobiles')"; static final String DING_TALK_AT_MOBILES = "$t('atMobiles')";
static final String NAME_DING_TALK_AT_MOBILES = "AtMobiles"; static final String NAME_DING_TALK_AT_MOBILES = "AtMobiles";

162
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java

@ -39,10 +39,8 @@ import org.apache.http.util.EntityUtils;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -64,6 +62,7 @@ public final class DingTalkSender {
private final String url; private final String url;
private final String keyword; private final String keyword;
private final String secret; private final String secret;
private String msgType;
private final String atMobiles; private final String atMobiles;
private final String atUserIds; private final String atUserIds;
@ -83,6 +82,7 @@ public final class DingTalkSender {
url = config.get(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK); url = config.get(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK);
keyword = config.get(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD); keyword = config.get(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD);
secret = config.get(DingTalkParamsConstants.NAME_DING_TALK_SECRET); secret = config.get(DingTalkParamsConstants.NAME_DING_TALK_SECRET);
msgType = config.get(DingTalkParamsConstants.NAME_DING_TALK_MSG_TYPE);
atMobiles = config.get(DingTalkParamsConstants.NAME_DING_TALK_AT_MOBILES); atMobiles = config.get(DingTalkParamsConstants.NAME_DING_TALK_AT_MOBILES);
atUserIds = config.get(DingTalkParamsConstants.NAME_DING_TALK_AT_USERIDS); atUserIds = config.get(DingTalkParamsConstants.NAME_DING_TALK_AT_USERIDS);
@ -121,33 +121,6 @@ public final class DingTalkSender {
return RequestConfig.custom().setProxy(httpProxy).build(); return RequestConfig.custom().setProxy(httpProxy).build();
} }
private String textToJsonString(String text) {
Map<String, Object> items = new HashMap<>();
items.put("msgtype", "text");
Map<String, String> textContent = new HashMap<>();
byte[] byt = StringUtils.getBytesUtf8(text);
String txt = StringUtils.newStringUtf8(byt);
textContent.put("content", txt);
items.put("text", textContent);
setMsgAt(items);
return JSONUtils.toJsonString(items);
}
private void setMsgAt(Map<String, Object> items) {
Map<String, Object> at = new HashMap<>();
String[] atMobileArray = org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(atMobiles) ? atMobiles.split(",") : new String[0];
String[] atUserArray = org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(atUserIds) ? atUserIds.split(",") : new String[0];
boolean isAtAll = Objects.isNull(atAll) ? false : atAll;
at.put("atMobiles", atMobileArray);
at.put("atUserIds", atUserArray);
at.put("isAtAll", isAtAll);
items.put("at", at);
}
private AlertResult checkSendDingTalkSendMsgResult(String result) { private AlertResult checkSendDingTalkSendMsgResult(String result) {
AlertResult alertResult = new AlertResult(); AlertResult alertResult = new AlertResult();
alertResult.setStatus("false"); alertResult.setStatus("false");
@ -173,6 +146,13 @@ public final class DingTalkSender {
return alertResult; return alertResult;
} }
/**
* send dingtalk msg handler
*
* @param title title
* @param content content
* @return
*/
public AlertResult sendDingTalkMsg(String title, String content) { public AlertResult sendDingTalkMsg(String title, String content) {
AlertResult alertResult; AlertResult alertResult;
try { try {
@ -189,18 +169,9 @@ public final class DingTalkSender {
private String sendMsg(String title, String content) throws IOException { private String sendMsg(String title, String content) throws IOException {
StringBuilder text = new StringBuilder(); String msg = generateMsgJson(title, content);
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(), msg);
HttpPost httpPost = constructHttpPost(org.apache.dolphinscheduler.spi.utils.StringUtils.isBlank(secret) ? url : generateSignedUrl(), msgToJson);
CloseableHttpClient httpClient; CloseableHttpClient httpClient;
if (Boolean.TRUE.equals(enableProxy)) { if (Boolean.TRUE.equals(enableProxy)) {
@ -221,13 +192,119 @@ public final class DingTalkSender {
} finally { } finally {
response.close(); response.close();
} }
logger.info("Ding Talk send title :{},content : {}, resp: {}", title, content, resp); logger.info("Ding Talk send msg :{}, resp: {}", msg, resp);
return resp; return resp;
} finally { } finally {
httpClient.close(); httpClient.close();
} }
} }
/**
* generate msg json
*
* @param title title
* @param content content
* @return msg
*/
private String generateMsgJson(String title, String content) {
if (org.apache.dolphinscheduler.spi.utils.StringUtils.isBlank(msgType)) {
msgType = DingTalkParamsConstants.DING_TALK_MSG_TYPE_TEXT;
}
Map<String, Object> items = new HashMap<>();
items.put("msgtype", msgType);
Map<String, Object> text = new HashMap<>();
items.put(msgType, text);
if (DingTalkParamsConstants.DING_TALK_MSG_TYPE_MARKDOWN.equals(msgType)) {
generateMarkdownMsg(title, content, text);
} else {
generateTextMsg(title, content, text);
}
setMsgAt(items);
return JSONUtils.toJsonString(items);
}
/**
* generate text msg
*
* @param title title
* @param content content
* @param text text
*/
private void generateTextMsg(String title, String content, Map<String, Object> text) {
StringBuilder builder = new StringBuilder(title);
builder.append("\n");
builder.append(content);
if (org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(keyword)) {
builder.append(" ");
builder.append(keyword);
}
byte[] byt = StringUtils.getBytesUtf8(builder.toString());
String txt = StringUtils.newStringUtf8(byt);
text.put("content", txt);
}
/**
* generate markdown msg
*
* @param title title
* @param content content
* @param text text
*/
private void generateMarkdownMsg(String title, String content, Map<String, Object> text) {
StringBuilder builder = new StringBuilder(content);
if (org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(keyword)) {
builder.append(" ");
builder.append(keyword);
}
builder.append("\n\n");
if (org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(atMobiles)) {
Arrays.stream(atMobiles.split(",")).forEach(value -> {
builder.append("@");
builder.append(value);
builder.append(" ");
});
}
if (org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(atUserIds)) {
Arrays.stream(atUserIds.split(",")).forEach(value -> {
builder.append("@");
builder.append(value);
builder.append(" ");
});
}
byte[] byt = StringUtils.getBytesUtf8(builder.toString());
String txt = StringUtils.newStringUtf8(byt);
text.put("title", title);
text.put("text", txt);
}
/**
* configure msg @person
*
* @param items items
*/
private void setMsgAt(Map<String, Object> items) {
Map<String, Object> at = new HashMap<>();
String[] atMobileArray = org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(atMobiles) ? atMobiles.split(",") : new String[0];
String[] atUserArray = org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(atUserIds) ? atUserIds.split(",") : new String[0];
boolean isAtAll = Objects.isNull(atAll) ? false : atAll;
at.put("atMobiles", atMobileArray);
at.put("atUserIds", atUserArray);
at.put("isAtAll", isAtAll);
items.put("at", at);
}
/**
* generate sign url
*
* @return sign url
*/
private String generateSignedUrl() { private String generateSignedUrl() {
Long timestamp = System.currentTimeMillis(); Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + secret; String stringToSign = timestamp + "\n" + secret;
@ -266,6 +343,7 @@ public final class DingTalkSender {
this.errmsg = errmsg; this.errmsg = errmsg;
} }
@Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o == this) { if (o == this) {
return true; return true;
@ -287,6 +365,7 @@ public final class DingTalkSender {
return true; return true;
} }
@Override
public int hashCode() { public int hashCode() {
final int PRIME = 59; final int PRIME = 59;
int result = 1; int result = 1;
@ -297,6 +376,7 @@ public final class DingTalkSender {
return result; return result;
} }
@Override
public String toString() { public String toString() {
return "DingTalkSender.DingTalkSendMsgResponse(errcode=" + this.getErrcode() + ", errmsg=" + this.getErrmsg() + ")"; return "DingTalkSender.DingTalkSendMsgResponse(errcode=" + this.getErrcode() + ", errmsg=" + this.getErrmsg() + ")";
} }

2
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(); DingTalkAlertChannelFactory dingTalkAlertChannelFactory = new DingTalkAlertChannelFactory();
List<PluginParams> params = dingTalkAlertChannelFactory.params(); List<PluginParams> params = dingTalkAlertChannelFactory.params();
JSONUtils.toJsonString(params); JSONUtils.toJsonString(params);
Assert.assertEquals(11, params.size()); Assert.assertEquals(12, params.size());
} }
@Test @Test

4
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSenderTest.java

@ -33,8 +33,10 @@ public class DingTalkSenderTest {
@Before @Before
public void initDingTalkConfig() { public void initDingTalkConfig() {
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, "keyWord"); dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, "keyword");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, "url"); dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, "url");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_MSG_TYPE, DingTalkParamsConstants.DING_TALK_MSG_TYPE_MARKDOWN);
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, "false"); dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, "false");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD, "password"); dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD, "password");
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PORT, "9988"); dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PORT, "9988");

1
dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js

@ -755,6 +755,7 @@ export default {
webHook: 'WebHook', webHook: 'WebHook',
Keyword: 'Keyword', Keyword: 'Keyword',
Secret: 'Secret', Secret: 'Secret',
MsgType: 'MsgType',
AtMobiles: '@Mobiles', AtMobiles: '@Mobiles',
AtUserIds: '@UserIds', AtUserIds: '@UserIds',
IsAtAll: '@All', IsAtAll: '@All',

1
dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -755,6 +755,7 @@ export default {
webHook: 'Web钩子', webHook: 'Web钩子',
Keyword: '关键词', Keyword: '关键词',
Secret: '密钥', Secret: '密钥',
MsgType: '消息类型',
AtMobiles: '@手机号', AtMobiles: '@手机号',
AtUserIds: '@用户ID', AtUserIds: '@用户ID',
IsAtAll: '@所有人', IsAtAll: '@所有人',

Loading…
Cancel
Save