This is an automated email from the ASF dual-hosted git repository. gaojun2048 pushed a commit to branch alert_plugin_design in repository https://gitbox.apache.org/repos/asf/incubator-dolphinscheduler.git
commit ce3d7d5b1259f7c43f5e346ed8860a4a1cee3dd0 Author: Kirs <[email protected]> AuthorDate: Mon Nov 2 10:08:28 2020 +0800 [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: break60 <[email protected]> * [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: break60 <[email protected]> Co-authored-by: gaojun2048 <[email protected]> --- .../dolphinscheduler-alert-dingtalk/pom.xml | 46 +++ .../alert/dingtalk/DingTalkAlertChannel.java | 41 +++ .../dingtalk/DingTalkAlertChannelFactory.java | 89 ++++++ .../plugin/alert/dingtalk/DingTalkAlertPlugin.java | 34 +++ .../alert/dingtalk/DingTalkParamsConstants.java | 54 ++++ .../plugin/alert/dingtalk/DingTalkSender.java | 204 +++++++++++++ .../dingtalk/DingTalkAlertChannelFactoryTest.java | 48 +++ .../plugin/alert/dingtalk/DingTalkSenderTest.java | 57 ++++ .../dolphinscheduler-alert-wechat/pom.xml | 42 +++ .../plugin/alert/wechat/WeChatAlertChannel.java | 41 +++ .../alert/wechat/WeChatAlertChannelFactory.java | 94 ++++++ .../plugin/alert/wechat/WeChatAlertConstants.java | 34 +++ .../alert/wechat/WeChatAlertParamsConstants.java | 56 ++++ .../plugin/alert/wechat/WeChatAlertPlugin.java | 34 +++ .../plugin/alert/wechat/WeChatSender.java | 328 +++++++++++++++++++++ .../wechat/WeChatAlertChannelFactoryTest.java | 48 +++ .../plugin/alert/wechat/WeChatSenderTest.java | 89 ++++++ .../alert/manager/DingTalkManager.java | 55 ---- .../alert/manager/EnterpriseWeChatManager.java | 63 ---- .../alert/utils/DingTalkUtils.java | 138 --------- .../alert/utils/EnterpriseWeChatUtils.java | 290 ------------------ .../alert/utils/DingTalkUtilsTest.java | 110 ------- .../alert/utils/EnterpriseWeChatUtilsTest.java | 307 ------------------- dolphinscheduler-spi/pom.xml | 2 + .../dolphinscheduler/spi/utils/JSONUtils.java | 2 +- pom.xml | 10 +- 26 files changed, 1349 insertions(+), 967 deletions(-) diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/pom.xml b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/pom.xml index 7a42257..8b47172 100644 --- a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/pom.xml +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/pom.xml @@ -29,4 +29,50 @@ <artifactId>dolphinscheduler-alert-dingtalk</artifactId> + <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> + </project> \ No newline at end of file diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannel.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannel.java new file mode 100644 index 0000000..7adfacc --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannel.java @@ -0,0 +1,41 @@ +/* + * 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()); + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java new file mode 100644 index 0000000..0126de4 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.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 "ding talk alert"; + } + + @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(true) + .build()) + .build(); + InputParam proxyParam = + InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY, DingTalkParamsConstants.DING_TALK_PROXY) + .addValidate(Validate.newBuilder() + .setRequired(true).build()) + .build(); + + InputParam portParam = InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PORT, DingTalkParamsConstants.DING_TALK_PORT) + .addValidate(Validate.newBuilder() + .setRequired(true).build()) + .build(); + + InputParam userParam = + InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_USER, DingTalkParamsConstants.DING_TALK_USER) + .addValidate(Validate.newBuilder() + .setRequired(true).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(); + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertPlugin.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertPlugin.java new file mode 100644 index 0000000..2d15f49 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertPlugin.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.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()); + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java new file mode 100644 index 0000000..6608e83 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.alert.dingtalk; + +/** + * DingTalkParamsConstants + */ +public class DingTalkParamsConstants { + + + 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"; + +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java new file mode 100644 index 0000000..e88d160 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java @@ -0,0 +1,204 @@ +/* + * 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.AlertResult; +import org.apache.dolphinscheduler.spi.utils.JSONUtils; + +import org.apache.commons.codec.binary.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCredentialsProvider; +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.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Ding Talk Sender + */ +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; + } + + 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(enableProxy)) { + httpClient = getProxyClient(proxy, port, user, password); + RequestConfig rcf = getProxyConfig(proxy, port); + httpPost.setConfig(rcf); + } else { + httpClient = getDefaultClient(); + } + + try { + CloseableHttpResponse response = httpClient.execute(httpPost); + String resp; + try { + HttpEntity entity = response.getEntity(); + resp = EntityUtils.toString(entity, charset); + EntityUtils.consume(entity); + } finally { + response.close(); + } + logger.info("Ding Talk send [%s], resp:{%s}", msg, resp); + return resp; + } finally { + httpClient.close(); + } + } + + 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; + } + + 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, password)); + return HttpClients.custom().setDefaultCredentialsProvider(provider).build(); + } + + private static CloseableHttpClient getDefaultClient() { + return HttpClients.createDefault(); + } + + private static RequestConfig getProxyConfig(String proxy, int port) { + HttpHost httpProxy = new HttpHost(proxy, port); + return RequestConfig.custom().setProxy(httpProxy).build(); + } + + private static 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); + 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; + } + +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java new file mode 100644 index 0000000..2a26daa --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java @@ -0,0 +1,48 @@ +/* + * 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); + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSenderTest.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSenderTest.java new file mode 100644 index 0000000..4512402 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSenderTest.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.alert.dingtalk; + +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; + +/** + * DingTalkSenderTest + */ +public class DingTalkSenderTest { + + private static Map<String, String> dingTalkConfig = new HashMap<>(); + + @Before + 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 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()); + } + +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/pom.xml b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/pom.xml index 62ac776..1600170 100644 --- a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/pom.xml +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/pom.xml @@ -27,6 +27,48 @@ <groupId>org.apache.dolphinscheduler</groupId> <artifactId>dolphinscheduler-alert-wechat</artifactId> + <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> </project> \ No newline at end of file diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannel.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannel.java new file mode 100644 index 0000000..4cdd4d3 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannel.java @@ -0,0 +1,41 @@ +/* + * 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()); + + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannelFactory.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannelFactory.java new file mode 100644 index 0000000..539add5 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannelFactory.java @@ -0,0 +1,94 @@ +/* + * 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 "we chat alert"; + } + + @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(); + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertConstants.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertConstants.java new file mode 100644 index 0000000..904060c --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertConstants.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.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}"; +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertParamsConstants.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertParamsConstants.java new file mode 100644 index 0000000..600e31e --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertParamsConstants.java @@ -0,0 +1,56 @@ +/* + * 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 = "enterprise.wechat.corp.id"; + + static final String NAME_ENTERPRISE_WE_CHAT_CORP_ID = "enterpriseWeChatCorpId"; + + + static final String ENTERPRISE_WE_CHAT_SECRET = "enterprise.wechat.secret"; + + static final String NAME_ENTERPRISE_WE_CHAT_SECRET = "enterpriseWeChatSecret"; + + static final String ENTERPRISE_WE_CHAT_TEAM_SEND_MSG = "enterprise.wechat.team.send.msg"; + + static final String NAME_ENTERPRISE_WE_CHAT_TEAM_SEND_MSG = "enterpriseWeChatTeamSendMsg"; + + + static final String ENTERPRISE_WE_CHAT_USER_SEND_MSG = "enterprise.wechat.user.send.msg"; + + static final String NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG = "enterpriseWeChatUserSendMsg"; + + + static final String ENTERPRISE_WE_CHAT_AGENT_ID = "enterprise.wechat.agent.id"; + + static final String NAME_ENTERPRISE_WE_CHAT_AGENT_ID = "enterpriseWeChatAgentId"; + + + static final String ENTERPRISE_WE_CHAT_USERS = "enterprise.wechat.users"; + + + static final String NAME_ENTERPRISE_WE_CHAT_USERS = "enterpriseWeChatUsers"; + + +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertPlugin.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertPlugin.java new file mode 100644 index 0000000..56c3c01 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertPlugin.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.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()); + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSender.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSender.java new file mode 100644 index 0000000..52397f5 --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSender.java @@ -0,0 +1,328 @@ +/* + * 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) { + List<String> userList = Arrays.asList(weChatUsers.split(",")); + String data = markdownByAlert(title, content); + String msg = makeUserSendMsg(userList, weChatAgentId, data); + String enterpriseWeChatPushUrlReplace = WeChatAlertConstants.WE_CHAT_PUSH_URL.replace(tokenRegex, weChatToken); + AlertResult alertResult; + 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) { + 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; + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/test/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannelFactoryTest.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/test/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannelFactoryTest.java new file mode 100644 index 0000000..cc62d5a --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/test/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertChannelFactoryTest.java @@ -0,0 +1,48 @@ +/* + * 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); + } +} diff --git a/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/test/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSenderTest.java b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/test/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSenderTest.java new file mode 100644 index 0000000..a6c4c4f --- /dev/null +++ b/dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/test/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSenderTest.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.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, "1000002"); + weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID, "ww8cc690c06761eaa3"); + weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET, "MYL0_O91ICNrdjkAhgeXIOAj4gEKIirf0-xoYnA25vg"); + 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("true", 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("true", alertResult.getStatus()); + } + +} diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/DingTalkManager.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/DingTalkManager.java deleted file mode 100644 index 07de6a0..0000000 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/DingTalkManager.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.alert.manager; - -import org.apache.dolphinscheduler.alert.utils.Constants; -import org.apache.dolphinscheduler.alert.utils.DingTalkUtils; -import org.apache.dolphinscheduler.spi.alert.AlertInfo; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Ding Talk Manager - */ -public class DingTalkManager { - private static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatManager.class); - - 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); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - retMap.put(Constants.STATUS, true); - return retMap; - } - - private String buildMessage(AlertInfo alert) { - String msg = alert.getAlertData().getContent(); - return msg; - } -} diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java deleted file mode 100644 index 0534d80..0000000 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EnterpriseWeChatManager.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.alert.manager; - -import org.apache.dolphinscheduler.alert.utils.Constants; -import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils; -import org.apache.dolphinscheduler.spi.alert.AlertInfo; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Enterprise WeChat Manager - */ -public class EnterpriseWeChatManager { - private static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatManager.class); - - /** - * Enterprise We Chat send - * - * @param alertInfo the alert info - * @param token the token - * @return the send result - */ - public Map<String, Object> send(AlertInfo alertInfo, String token) { - Map<String, Object> retMap = new HashMap<>(); - retMap.put(Constants.STATUS, false); - String agentId = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_AGENT_ID; - String users = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_USERS; - List<String> userList = Arrays.asList(users.split(",")); - logger.info("send message {}", alertInfo.getAlertData().getTitle()); - String msg = EnterpriseWeChatUtils.makeUserSendMsg(userList, agentId, EnterpriseWeChatUtils.markdownByAlert(alertInfo)); - try { - EnterpriseWeChatUtils.sendEnterpriseWeChat(Constants.UTF_8, msg, token); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - retMap.put(Constants.STATUS, true); - return retMap; - } - -} diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/DingTalkUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/DingTalkUtils.java deleted file mode 100644 index abac8ae..0000000 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/DingTalkUtils.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.alert.utils; - -import org.apache.dolphinscheduler.common.utils.JSONUtils; - -import org.apache.commons.codec.binary.StringUtils; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.BasicCredentialsProvider; -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.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * DingTalkUtils utils - * support send msg to ding talk by robot message push function. - * support proxy setting - */ -public class DingTalkUtils { - public static final Logger logger = LoggerFactory.getLogger(DingTalkUtils.class); - - public static final boolean isEnableDingTalk = PropertyUtils.getBoolean(Constants.DINGTALK_ENABLE); - private static final String dingTaskUrl = PropertyUtils.getString(Constants.DINGTALK_WEBHOOK); - private static final String keyword = PropertyUtils.getString(Constants.DINGTALK_KEYWORD); - private static final Boolean isEnableProxy = 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); - - /** - * 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); - - CloseableHttpClient httpClient; - if (isEnableProxy) { - httpClient = getProxyClient(); - RequestConfig rcf = getProxyConfig(); - httpPost.setConfig(rcf); - } else { - httpClient = getDefaultClient(); - } - - try { - CloseableHttpResponse response = httpClient.execute(httpPost); - String resp; - try { - HttpEntity entity = response.getEntity(); - resp = EntityUtils.toString(entity, charset); - EntityUtils.consume(entity); - } finally { - response.close(); - } - logger.info("Ding Talk send [{}], resp:{%s}", msg, resp); - return resp; - } finally { - httpClient.close(); - } - } - - public static HttpPost constructHttpPost(String msg, String charset) { - HttpPost post = new HttpPost(dingTaskUrl); - 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); - CredentialsProvider provider = new BasicCredentialsProvider(); - provider.setCredentials(new AuthScope(httpProxy), new UsernamePasswordCredentials(user, passwd)); - CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(provider).build(); - return httpClient; - } - - public static CloseableHttpClient getDefaultClient() { - return HttpClients.createDefault(); - } - - public static RequestConfig getProxyConfig() { - HttpHost httpProxy = new HttpHost(proxy, port); - return RequestConfig.custom().setProxy(httpProxy).build(); - } - - public static String textToJsonString(String text) { - Map<String, Object> items = new HashMap<String, Object>(); - items.put("msgtype", "text"); - Map<String, String> textContent = new HashMap<String, String>(); - byte[] byt = StringUtils.getBytesUtf8(text); - String txt = StringUtils.newStringUtf8(byt); - textContent.put("content", txt); - items.put("text", textContent); - - return JSONUtils.toJsonString(items); - - } - -} diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java deleted file mode 100644 index 17a49e3..0000000 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtils.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.alert.utils; - -import org.apache.dolphinscheduler.common.utils.JSONUtils; -import org.apache.dolphinscheduler.common.utils.StringUtils; -import org.apache.dolphinscheduler.spi.alert.AlertConstants; -import org.apache.dolphinscheduler.spi.alert.AlertInfo; -import org.apache.dolphinscheduler.spi.alert.ShowType; -import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer; - -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.Collection; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Enterprise WeChat utils - */ -public class EnterpriseWeChatUtils { - - public static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatUtils.class); - public static final String ENTERPRISE_WE_CHAT_AGENT_ID = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_AGENT_ID); - public static final String ENTERPRISE_WE_CHAT_USERS = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USERS); - private static final String ENTERPRISE_WE_CHAT_CORP_ID = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_CORP_ID); - private static final String ENTERPRISE_WE_CHAT_SECRET = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_SECRET); - private static final String ENTERPRISE_WE_CHAT_TOKEN_URL = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_TOKEN_URL); - private static final String ENTERPRISE_WE_CHAT_TOKEN_URL_REPLACE = ENTERPRISE_WE_CHAT_TOKEN_URL == null ? null : ENTERPRISE_WE_CHAT_TOKEN_URL - .replaceAll("\\{corpId}", ENTERPRISE_WE_CHAT_CORP_ID) - .replaceAll("\\{secret}", ENTERPRISE_WE_CHAT_SECRET); - private static final String ENTERPRISE_WE_CHAT_PUSH_URL = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_PUSH_URL); - private static final String ENTERPRISE_WE_CHAT_TEAM_SEND_MSG = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_TEAM_SEND_MSG); - private static final String ENTERPRISE_WE_CHAT_USER_SEND_MSG = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USER_SEND_MSG); - - private static final String agentIdRegExp = "\\{agentId}"; - private static final String msgRegExp = "\\{msg}"; - private static final String userRegExp = "\\{toUser}"; - - /** - * get Enterprise WeChat is enable - * - * @return isEnable - */ - public static boolean isEnable() { - Boolean isEnable = null; - try { - isEnable = PropertyUtils.getBoolean(Constants.ENTERPRISE_WECHAT_ENABLE); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - if (isEnable == null) { - return false; - } - return isEnable; - } - - /** - * get Enterprise WeChat token info - * - * @return token string info - * @throws IOException the IOException - */ - public static String getToken() throws IOException { - String resp; - - CloseableHttpClient httpClient = HttpClients.createDefault(); - try { - HttpGet httpGet = new HttpGet(ENTERPRISE_WE_CHAT_TOKEN_URL_REPLACE); - CloseableHttpResponse response = httpClient.execute(httpGet); - try { - HttpEntity entity = response.getEntity(); - resp = EntityUtils.toString(entity, Constants.UTF_8); - EntityUtils.consume(entity); - } finally { - response.close(); - } - - Map<String, String> map = JSONUtils.toMap(resp); - if (map != null) { - return map.get("access_token"); - } else { - return null; - } - } finally { - httpClient.close(); - } - } - - /** - * make team single Enterprise WeChat message - * - * @param toParty the toParty - * @param agentId the agentId - * @param msg the msg - * @return Enterprise WeChat send message - */ - public static String makeTeamSendMsg(String toParty, String agentId, String msg) { - return ENTERPRISE_WE_CHAT_TEAM_SEND_MSG.replaceAll("\\{toParty}", toParty) - .replaceAll(agentIdRegExp, agentId) - .replaceAll(msgRegExp, msg); - } - - /** - * make team multi Enterprise WeChat message - * - * @param toParty the toParty - * @param agentId the agentId - * @param msg the msg - * @return Enterprise WeChat send message - */ - public static String makeTeamSendMsg(Collection<String> toParty, String agentId, String msg) { - String listParty = FuncUtils.mkString(toParty, "|"); - return ENTERPRISE_WE_CHAT_TEAM_SEND_MSG.replaceAll("\\{toParty}", listParty) - .replaceAll(agentIdRegExp, agentId) - .replaceAll(msgRegExp, msg); - } - - /** - * make team single user message - * - * @param toUser the toUser - * @param agentId the agentId - * @param msg the msg - * @return Enterprise WeChat send message - */ - public static String makeUserSendMsg(String toUser, String agentId, String msg) { - return ENTERPRISE_WE_CHAT_USER_SEND_MSG.replaceAll("\\{toUser}", toUser) - .replaceAll(agentIdRegExp, agentId) - .replaceAll(msgRegExp, msg); - } - - /** - * make team multi user message - * - * @param toUser the toUser - * @param agentId the agentId - * @param msg the msg - * @return Enterprise WeChat send message - */ - public static String makeUserSendMsg(Collection<String> toUser, String agentId, String msg) { - String listUser = FuncUtils.mkString(toUser, "|"); - return ENTERPRISE_WE_CHAT_USER_SEND_MSG.replaceAll(userRegExp, listUser) - .replaceAll(agentIdRegExp, agentId) - .replaceAll(msgRegExp, msg); - } - - /** - * send Enterprise WeChat - * - * @param charset the charset - * @param data the data - * @param token the token - * @return Enterprise WeChat resp, demo: {"errcode":0,"errmsg":"ok","invaliduser":""} - * @throws IOException the IOException - */ - public static String sendEnterpriseWeChat(String charset, String data, String token) throws IOException { - String enterpriseWeChatPushUrlReplace = ENTERPRISE_WE_CHAT_PUSH_URL.replaceAll("\\{token}", token); - - CloseableHttpClient httpClient = HttpClients.createDefault(); - try { - HttpPost httpPost = new HttpPost(enterpriseWeChatPushUrlReplace); - httpPost.setEntity(new StringEntity(data, charset)); - CloseableHttpResponse response = httpClient.execute(httpPost); - String resp; - try { - HttpEntity entity = response.getEntity(); - resp = EntityUtils.toString(entity, charset); - EntityUtils.consume(entity); - } finally { - response.close(); - } - logger.info("Enterprise WeChat send [{}], param:{}, resp:{}", - ENTERPRISE_WE_CHAT_PUSH_URL, data, resp); - return resp; - } finally { - httpClient.close(); - } - } - - /** - * convert table to markdown style - * - * @param title the title - * @param content the content - * @return markdown table content - */ - public static String markdownTable(String title, String content) { - List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class); - StringBuilder contents = new StringBuilder(200); - - if (null != mapItemsList) { - for (LinkedHashMap mapItems : mapItemsList) { - Set<Map.Entry<String, Object>> entries = mapItems.entrySet(); - Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); - StringBuilder t = new StringBuilder(String.format("`%s`%s", title, Constants.MARKDOWN_ENTER)); - - while (iterator.hasNext()) { - - Map.Entry<String, Object> entry = iterator.next(); - t.append(Constants.MARKDOWN_QUOTE); - t.append(entry.getKey()).append(":").append(entry.getValue()); - t.append(Constants.MARKDOWN_ENTER); - } - contents.append(t); - } - } - return contents.toString(); - } - - /** - * convert text to markdown style - * - * @param title the title - * @param content the content - * @return markdown text - */ - public static String markdownText(String title, String content) { - if (StringUtils.isNotEmpty(content)) { - List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class); - if (null != mapItemsList) { - StringBuilder contents = new StringBuilder(100); - contents.append(String.format("`%s`%n", title)); - for (LinkedHashMap mapItems : mapItemsList) { - - Set<Map.Entry<String, Object>> entries = mapItems.entrySet(); - Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); - while (iterator.hasNext()) { - Map.Entry<String, Object> entry = iterator.next(); - contents.append(Constants.MARKDOWN_QUOTE); - contents.append(entry.getKey()).append(":").append(entry.getValue()); - contents.append(Constants.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 - */ - public static String markdownByAlert(AlertInfo alertInfo) { - String result = ""; - Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertInfo.getAlertParams()); - String showType = paramsMap.get(AlertConstants.SHOW_TYPE); - if (showType.equals(ShowType.TABLE.getDescp())) { - result = markdownTable(alertInfo.getAlertData().getTitle(), alertInfo.getAlertData().getContent()); - } else if (showType.equals(ShowType.TEXT.getDescp())) { - result = markdownText(alertInfo.getAlertData().getTitle(), alertInfo.getAlertData().getContent()); - } - return result; - - } - -} diff --git a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/DingTalkUtilsTest.java b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/DingTalkUtilsTest.java deleted file mode 100644 index 27c481e..0000000 --- a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/DingTalkUtilsTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.alert.utils; - -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.IOException; - -import org.junit.Assert; -import org.junit.Before; -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.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@PrepareForTest(PropertyUtils.class) -@RunWith(PowerMockRunner.class) -@PowerMockIgnore("javax.net.ssl.*") -public class DingTalkUtilsTest { - Logger logger = LoggerFactory.getLogger(DingTalkUtilsTest.class); - - private static final String mockUrl = "https://oapi.dingtalk.com/robot/send?access_token=test"; - private static final String mockKeyWords = "onway"; - private static final String msg = "ding talk test"; - - @Before - public void init() { - PowerMockito.mockStatic(PropertyUtils.class); - Mockito.when(PropertyUtils.getString(Constants.DINGTALK_WEBHOOK)).thenReturn(mockUrl); - Mockito.when(PropertyUtils.getString(Constants.DINGTALK_KEYWORD)).thenReturn(mockKeyWords); - Mockito.when(PropertyUtils.getBoolean(Constants.DINGTALK_PROXY_ENABLE)).thenReturn(true); - Mockito.when(PropertyUtils.getString(Constants.DINGTALK_PROXY)).thenReturn("proxy.com.cn"); - Mockito.when(PropertyUtils.getString(Constants.DINGTALK_USER)).thenReturn("user"); - Mockito.when(PropertyUtils.getString(Constants.DINGTALK_PASSWORD)).thenReturn("pswd"); - Mockito.when(PropertyUtils.getInt(Constants.DINGTALK_PORT)).thenReturn(80); - } - - @Test - public void testCreateDefaultClient() { - CloseableHttpClient client = DingTalkUtils.getDefaultClient(); - try { - Assert.assertNotNull(client); - client.close(); - } catch (IOException ex) { - logger.info("close exception", ex.getMessage()); - new Throwable(); - } - } - - @Test - public void testCreateProxyClient() { - CloseableHttpClient client = DingTalkUtils.getProxyClient(); - try { - Assert.assertNotNull(client); - client.close(); - } catch (IOException ex) { - logger.info("close exception", ex.getMessage()); - new Throwable(); - } - - } - - @Test - public void testProxyConfig() { - RequestConfig rc = DingTalkUtils.getProxyConfig(); - Assert.assertEquals(rc.getProxy().getPort(), 80); - Assert.assertEquals(rc.getProxy().getHostName(), "proxy.com.cn"); - } - - @Test - public void testDingTalkMsgToJson() { - String jsonString = DingTalkUtils.textToJsonString("this is test"); - - logger.info(jsonString); - String expect = "{\"text\":{\"content\":\"this is test\"},\"msgtype\":\"text\"}"; - Assert.assertEquals(expect, jsonString); - } - - @Test - public void testDingTalkMsgUtf8() { - String msg = DingTalkUtils.textToJsonString("this is test:中文"); - - logger.info("test support utf8, actual:" + msg); - logger.info("test support utf8, actual:" + DingTalkUtils.isEnableDingTalk); - String expect = "{\"text\":{\"content\":\"this is test:中文\"},\"msgtype\":\"text\"}"; - Assert.assertEquals(expect, msg); - } - -} diff --git a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java deleted file mode 100644 index d528d2c..0000000 --- a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/EnterpriseWeChatUtilsTest.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.alert.utils; - -import org.apache.dolphinscheduler.common.enums.AlertType; -import org.apache.dolphinscheduler.common.utils.JSONUtils; -import org.apache.dolphinscheduler.dao.entity.Alert; -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.ShowType; -import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer; -import org.apache.dolphinscheduler.spi.params.RadioParam; -import org.apache.dolphinscheduler.spi.params.base.PluginParams; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; - -import org.junit.Assert; -import org.junit.Before; -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; - -/** - * Please manually modify the configuration file before testing. - * file: alert.properties - * enterprise.wechat.corp.id - * enterprise.wechat.secret - * enterprise.wechat.token.url - * enterprise.wechat.push.url - * enterprise.wechat.send.msg - * enterprise.wechat.agent.id - * enterprise.wechat.users - */ - -@PrepareForTest(PropertyUtils.class) -@RunWith(PowerMockRunner.class) -public class EnterpriseWeChatUtilsTest { - - private static final String toParty = "wwc99134b6fc1edb6"; - private static final String enterpriseWechatSecret = "Uuv2KFrkdf7SeKOsTDCpsTkpawXBMNRhFy6VKX5FV"; - private static final String enterpriseWechatAgentId = "1000004"; - private static final String enterpriseWechatUsers = "LiGang,journey"; - private static final String msg = "hello world"; - - private static final String enterpriseWechatTeamSendMsg = "{\\\"toparty\\\":\\\"{toParty}\\\",\\\"agentid\\\":\\\"{agentId}\\\"" - + - ",\\\"msgtype\\\":\\\"text\\\",\\\"text\\\":{\\\"content\\\":\\\"{msg}\\\"},\\\"safe\\\":\\\"0\\\"}"; - private static final String enterpriseWechatUserSendMsg = "{\\\"touser\\\":\\\"{toUser}\\\",\\\"agentid\\\":\\\"{agentId}\\\"" - + - ",\\\"msgtype\\\":\\\"markdown\\\",\\\"markdown\\\":{\\\"content\\\":\\\"{msg}\\\"}}"; - - @Before - public void init() { - PowerMockito.mockStatic(PropertyUtils.class); - Mockito.when(PropertyUtils.getBoolean(Constants.ENTERPRISE_WECHAT_ENABLE)).thenReturn(true); - Mockito.when(PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USER_SEND_MSG)).thenReturn(enterpriseWechatUserSendMsg); - Mockito.when(PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_TEAM_SEND_MSG)).thenReturn(enterpriseWechatTeamSendMsg); - } - - @Test - public void testIsEnable() { - Boolean weChartEnable = EnterpriseWeChatUtils.isEnable(); - Assert.assertTrue(weChartEnable); - } - - @Test - public void testMakeTeamSendMsg1() { - String sendMsg = EnterpriseWeChatUtils.makeTeamSendMsg(toParty, enterpriseWechatSecret, msg); - Assert.assertTrue(sendMsg.contains(toParty)); - Assert.assertTrue(sendMsg.contains(enterpriseWechatSecret)); - Assert.assertTrue(sendMsg.contains(msg)); - - } - - @Test - public void testMakeTeamSendMsg2() { - List<String> parties = new ArrayList<>(); - parties.add(toParty); - parties.add("test1"); - - String sendMsg = EnterpriseWeChatUtils.makeTeamSendMsg(parties, enterpriseWechatSecret, msg); - Assert.assertTrue(sendMsg.contains(toParty)); - Assert.assertTrue(sendMsg.contains(enterpriseWechatSecret)); - Assert.assertTrue(sendMsg.contains(msg)); - } - - @Test - public void tesMakeUserSendMsg1() { - - String sendMsg = EnterpriseWeChatUtils.makeUserSendMsg(enterpriseWechatUsers, enterpriseWechatAgentId, msg); - Assert.assertTrue(sendMsg.contains(enterpriseWechatUsers)); - Assert.assertTrue(sendMsg.contains(enterpriseWechatAgentId)); - Assert.assertTrue(sendMsg.contains(msg)); - } - - @Test - public void tesMakeUserSendMsg2() { - List<String> users = new ArrayList<>(); - users.add("user1"); - users.add("user2"); - - String sendMsg = EnterpriseWeChatUtils.makeUserSendMsg(users, enterpriseWechatAgentId, msg); - Assert.assertTrue(sendMsg.contains(users.get(0))); - Assert.assertTrue(sendMsg.contains(users.get(1))); - Assert.assertTrue(sendMsg.contains(enterpriseWechatAgentId)); - Assert.assertTrue(sendMsg.contains(msg)); - } - - @Test - public void testMarkdownByAlertForText() { - Alert alertForText = createAlertForText(); - AlertData alertData = new AlertData(); - AlertInfo alertInfo = new AlertInfo(); - //TODO: - List<PluginParams> paramsList = new ArrayList<>(); - RadioParam showType = new RadioParam.Builder(AlertConstants.SHOW_TYPE, AlertConstants.SHOW_TYPE) - .setValue(ShowType.TEXT) - .build(); - paramsList.add(showType); - alertInfo.setAlertParams(PluginParamsTransfer.transferParamsToJson(paramsList)); - alertInfo.setAlertData(alertData); - alertData.setTitle(alertForText.getTitle()) - //.setShowType(alertForText.getShowType().getDescp()) - .setContent(alertForText.getContent()); - String result = EnterpriseWeChatUtils.markdownByAlert(alertInfo); - Assert.assertNotNull(result); - } - - @Test - public void testMarkdownByAlertForTable() { - Alert alertForText = createAlertForTable(); - AlertData alertData = new AlertData(); - AlertInfo alertInfo = new AlertInfo(); - //TODO: - List<PluginParams> paramsList = new ArrayList<>(); - RadioParam showType = new RadioParam.Builder(AlertConstants.SHOW_TYPE, AlertConstants.SHOW_TYPE) - .setValue(ShowType.TABLE) - .build(); - paramsList.add(showType); - alertInfo.setAlertParams(PluginParamsTransfer.transferParamsToJson(paramsList)); - alertInfo.setAlertData(alertData); - alertData.setTitle(alertForText.getTitle()) - //.setShowType(alertForText.getShowType().getDescp()) - .setContent(alertForText.getContent()); - String result = EnterpriseWeChatUtils.markdownByAlert(alertInfo); - Assert.assertNotNull(result); - } - - private Alert createAlertForText() { - 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\"}]"; - - Alert alert = new Alert(); - alert.setTitle("Mysql Exception"); - //alert.setShowType(ShowType.TEXT); - alert.setContent(content); - alert.setAlertType(AlertType.EMAIL); - alert.setAlertGroupId(4); - - return alert; - } - - 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("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); - return mapjson; - } - - private Alert createAlertForTable() { - Alert alert = new Alert(); - alert.setTitle("Mysql Exception"); - //alert.setShowType(ShowType.TABLE.getDescp()); - String content = list2String(); - alert.setContent(content); - alert.setAlertType(AlertType.EMAIL); - alert.setAlertGroupId(1); - return alert; - } - - - // @Test - // public void testSendSingleTeamWeChat() { - // try { - // String token = EnterpriseWeChatUtils.getToken(); - // String msg = EnterpriseWeChatUtils.makeTeamSendMsg(partyId, agentId, "hello world"); - // String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token); - // - // String errmsg = JSONUtils.parseObject(resp).getString("errmsg"); - // Assert.assertEquals("ok",errmsg); - // } catch (IOException e) { - // e.printStackTrace(); - // } - // } - // - // @Test - // public void testSendMultiTeamWeChat() { - // - // try { - // String token = EnterpriseWeChatUtils.getToken(); - // String msg = EnterpriseWeChatUtils.makeTeamSendMsg(listPartyId, agentId, "hello world"); - // String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token); - // - // String errmsg = JSONUtils.parseObject(resp).getString("errmsg"); - // Assert.assertEquals("ok",errmsg); - // } catch (IOException e) { - // e.printStackTrace(); - // } - // } - // - // @Test - // public void testSendSingleUserWeChat() { - // try { - // String token = EnterpriseWeChatUtils.getToken(); - // String msg = EnterpriseWeChatUtils.makeUserSendMsg(listUserId.stream().findFirst().get(), agentId, "your meeting room has been booked and will be synced to the 'mailbox' later \n" + - // ">**matter details** \n" + - // ">matter:<font color='info'>meeting</font> <br>" + - // ">organizer:@miglioguan \n" + - // ">participant:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang \n" + - // "> \n" + - // ">meeting room:<font color='info'>Guangzhou TIT 1st Floor 301</font> \n" + - // ">date:<font color='warning'>May 18, 2018</font> \n" + - // ">time:<font color='comment'>9:00-11:00 am</font> \n" + - // "> \n" + - // ">please attend the meeting on time\n" + - // "> \n" + - // ">to modify the meeting information, please click: [Modify Meeting Information](https://work.weixin.qq.com)\""); - // - // String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token); - // - // String errmsg = JSONUtils.parseObject(resp).getString("errmsg"); - // Assert.assertEquals("ok",errmsg); - // } catch (IOException e) { - // e.printStackTrace(); - // } - // } - // - // @Test - // public void testSendMultiUserWeChat() { - // try { - // String token = EnterpriseWeChatUtils.getToken(); - // - // String msg = EnterpriseWeChatUtils.makeUserSendMsg(listUserId, agentId, "hello world"); - // String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token); - // - // String errmsg = JSONUtils.parseObject(resp).getString("errmsg"); - // Assert.assertEquals("ok",errmsg); - // } catch (IOException e) { - // e.printStackTrace(); - // } - // } - -} diff --git a/dolphinscheduler-spi/pom.xml b/dolphinscheduler-spi/pom.xml index 50ed17e..dd0bae8 100644 --- a/dolphinscheduler-spi/pom.xml +++ b/dolphinscheduler-spi/pom.xml @@ -35,10 +35,12 @@ <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </dependency> + <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> + <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/JSONUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/JSONUtils.java index e48686e..6542ef8 100644 --- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/JSONUtils.java +++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/JSONUtils.java @@ -153,4 +153,4 @@ public class JSONUtils { throw new RuntimeException("Json deserialization exception.", e); } } -} +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index d854a3a..eb43e00 100644 --- a/pom.xml +++ b/pom.xml @@ -687,9 +687,9 @@ <artifactId>dolphinscheduler-maven-plugin</artifactId> <extensions>true</extensions> <!--<configuration>--> - <!--<allowedProvidedDependencies>--> - <!--<allowedProvidedDependency>org.apache.dolphinscheduler:dolphinscheduler-common</allowedProvidedDependency>--> - <!--</allowedProvidedDependencies>--> + <!--<allowedProvidedDependencies>--> + <!--<allowedProvidedDependency>org.apache.dolphinscheduler:dolphinscheduler-common</allowedProvidedDependency>--> + <!--</allowedProvidedDependencies>--> <!--</configuration>--> </plugin> @@ -951,6 +951,10 @@ <include>**/plugin/alert/email/ExcelUtilsTest.java</include> <include>**/plugin/alert/email/MailUtilsTest.java</include> <include>**/plugin/alert/email/template/DefaultHTMLTemplateTest.java</include> + <include>**/plugin/alert/dingtalk/DingTalkSenderTest.java</include> + <include>**/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java</include> + <include>**/plugin/alert/wechat/WeChatSenderTest.java</include> + <include>**/plugin/alert/wechat/WeChatAlertChannelFactoryTest.java</include> <include>**/spi/params/PluginParamsTransferTest.java</include> <include>**/alert/plugin/EmailAlertPluginTest.java</include> <include>**/alert/plugin/AlertPluginManagerTest.java</include>
