diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java index 58a37c2f41..dafa33adac 100644 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java +++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/AlertServer.java @@ -16,8 +16,11 @@ */ package org.apache.dolphinscheduler.alert; +import org.apache.dolphinscheduler.alert.plugin.EmailAlertPlugin; import org.apache.dolphinscheduler.alert.runner.AlertSender; import org.apache.dolphinscheduler.alert.utils.Constants; +import org.apache.dolphinscheduler.alert.utils.PropertyUtils; +import org.apache.dolphinscheduler.common.plugin.FilePluginManager; import org.apache.dolphinscheduler.common.thread.Stopper; import org.apache.dolphinscheduler.dao.AlertDao; import org.apache.dolphinscheduler.dao.DaoFactory; @@ -25,6 +28,7 @@ import org.apache.dolphinscheduler.dao.entity.Alert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.net.MalformedURLException; import java.util.List; /** @@ -41,34 +45,52 @@ public class AlertServer { private static AlertServer instance; - public AlertServer() { + private FilePluginManager alertPluginManager; + + private static final String[] whitePrefixes = new String[]{"org.apache.dolphinscheduler.plugin.utils."}; + + private static final String[] excludePrefixes = new String[]{ + "org.apache.dolphinscheduler.plugin.", + "ch.qos.logback.", + "org.slf4j." + }; + public AlertServer() { + try { + alertPluginManager = + new FilePluginManager(PropertyUtils.getString(Constants.PLUGIN_DIR), whitePrefixes, excludePrefixes); + // add default alert plugins + alertPluginManager.addPlugin(new EmailAlertPlugin()); + } catch (MalformedURLException e) { + logger.error("Failed to start alert server", e); + System.exit(1); + } } - public synchronized static AlertServer getInstance(){ + public synchronized static AlertServer getInstance() { if (null == instance) { instance = new AlertServer(); } return instance; } - public void start(){ + public void start() { logger.info("alert server ready start "); - while (Stopper.isRunning()){ + while (Stopper.isRunning()) { try { Thread.sleep(Constants.ALERT_SCAN_INTERVAL); } catch (InterruptedException e) { - logger.error(e.getMessage(),e); + logger.error(e.getMessage(), e); Thread.currentThread().interrupt(); } List alerts = alertDao.listWaitExecutionAlert(); - alertSender = new AlertSender(alerts, alertDao); + alertSender = new AlertSender(alerts, alertDao, alertPluginManager); alertSender.run(); } } - public static void main(String[] args){ + public static void main(String[] args) { AlertServer alertServer = AlertServer.getInstance(); alertServer.start(); } diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java index 047ee8bfed..8e78971594 100644 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java +++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/manager/EmailManager.java @@ -35,7 +35,7 @@ public class EmailManager { * @param showType the showType * @return the send result */ - public Map send(List receviersList,List receviersCcList,String title,String content,ShowType showType){ + public Map send(List receviersList,List receviersCcList,String title,String content,String showType){ return MailUtils.sendMails(receviersList, receviersCcList, title, content, showType); } @@ -48,7 +48,7 @@ public class EmailManager { * @param showType the showType * @return the send result */ - public Map send(List receviersList,String title,String content,ShowType showType){ + public Map send(List receviersList,String title,String content,String showType){ return MailUtils.sendMails(receviersList,title, content, showType); } 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 index bb06be6561..43649d6758 100644 --- 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 @@ -18,7 +18,7 @@ package org.apache.dolphinscheduler.alert.manager; import org.apache.dolphinscheduler.alert.utils.Constants; import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils; -import org.apache.dolphinscheduler.dao.entity.Alert; +import org.apache.dolphinscheduler.plugin.model.AlertInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,18 +35,18 @@ public class EnterpriseWeChatManager { private static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatManager.class); /** * Enterprise We Chat send - * @param alert the alert + * @param alertInfo the alert info * @param token the token * @return the send result */ - public Map send(Alert alert, String token){ + public Map send(AlertInfo alertInfo, String token){ Map retMap = new HashMap<>(); retMap.put(Constants.STATUS, false); String agentId = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_AGENT_ID; String users = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_USERS; List userList = Arrays.asList(users.split(",")); - logger.info("send message {}",alert); - String msg = EnterpriseWeChatUtils.makeUserSendMsg(userList, agentId,EnterpriseWeChatUtils.markdownByAlert(alert)); + logger.info("send message {}", alertInfo.getAlertData().getTitle()); + String msg = EnterpriseWeChatUtils.makeUserSendMsg(userList, agentId,EnterpriseWeChatUtils.markdownByAlert(alertInfo.getAlertData())); try { EnterpriseWeChatUtils.sendEnterpriseWeChat(Constants.UTF_8, msg, token); } catch (IOException e) { diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPlugin.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPlugin.java new file mode 100644 index 0000000000..d20306b153 --- /dev/null +++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPlugin.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dolphinscheduler.alert.plugin; + +import org.apache.dolphinscheduler.alert.manager.EmailManager; +import org.apache.dolphinscheduler.alert.manager.EnterpriseWeChatManager; +import org.apache.dolphinscheduler.alert.utils.Constants; +import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils; +import org.apache.dolphinscheduler.common.utils.CollectionUtils; +import org.apache.dolphinscheduler.common.utils.StringUtils; +import org.apache.dolphinscheduler.plugin.api.AlertPlugin; +import org.apache.dolphinscheduler.plugin.model.AlertData; +import org.apache.dolphinscheduler.plugin.model.AlertInfo; +import org.apache.dolphinscheduler.plugin.model.PluginName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * EmailAlertPlugin + * + * This plugin is a default plugin, and mix up email and enterprise wechat, because adapt with former alert behavior + */ +public class EmailAlertPlugin implements AlertPlugin { + + private static final Logger logger = LoggerFactory.getLogger(EmailAlertPlugin.class); + + private PluginName pluginName; + + private static final EmailManager emailManager = new EmailManager(); + private static final EnterpriseWeChatManager weChatManager = new EnterpriseWeChatManager(); + + public EmailAlertPlugin() { + this.pluginName = new PluginName(); + this.pluginName.setEnglish(Constants.PLUGIN_DEFAULT_EMAIL_EN); + this.pluginName.setChinese(Constants.PLUGIN_DEFAULT_EMAIL_CH); + } + + @Override + public String getId() { + return Constants.PLUGIN_DEFAULT_EMAIL; + } + + @Override + public PluginName getName() { + return pluginName; + } + + @Override + @SuppressWarnings("unchecked") + public Map process(AlertInfo info) { + Map retMaps = new HashMap<>(); + + AlertData alert = info.getAlertData(); + + List receviersList = (List) info.getProp(Constants.PLUGIN_DEFAULT_EMAIL_RECEIVERS); + + // receiving group list + // custom receiver + String receivers = alert.getReceivers(); + if (StringUtils.isNotEmpty(receivers)) { + String[] splits = receivers.split(","); + receviersList.addAll(Arrays.asList(splits)); + } + + List receviersCcList = new ArrayList<>(); + // Custom Copier + String receiversCc = alert.getReceiversCc(); + if (StringUtils.isNotEmpty(receiversCc)) { + String[] splits = receiversCc.split(","); + receviersCcList.addAll(Arrays.asList(splits)); + } + + if (CollectionUtils.isEmpty(receviersList) && CollectionUtils.isEmpty(receviersCcList)) { + logger.warn("alert send error : At least one receiver address required"); + retMaps.put(Constants.STATUS, "false"); + retMaps.put(Constants.MESSAGE, "execution failure,At least one receiver address required."); + return retMaps; + } + + retMaps = emailManager.send(receviersList, receviersCcList, alert.getTitle(), alert.getContent(), + alert.getShowType()); + + //send flag + boolean flag = false; + + if (retMaps == null) { + retMaps = new HashMap<>(); + retMaps.put(Constants.MESSAGE, "alert send error."); + retMaps.put(Constants.STATUS, "false"); + logger.info("alert send error : {}", retMaps.get(Constants.MESSAGE)); + return retMaps; + } + + flag = Boolean.parseBoolean(String.valueOf(retMaps.get(Constants.STATUS))); + + if (flag) { + logger.info("alert send success"); + retMaps.put(Constants.MESSAGE, "email send success."); + if (EnterpriseWeChatUtils.isEnable()) { + logger.info("Enterprise WeChat is enable!"); + try { + String token = EnterpriseWeChatUtils.getToken(); + weChatManager.send(info, token); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + + } else { + retMaps.put(Constants.MESSAGE, "alert send error."); + logger.info("alert send error : {}", retMaps.get(Constants.MESSAGE)); + } + + return retMaps; + } + +} diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java index 5feb36b60f..071877ae54 100644 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java +++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/runner/AlertSender.java @@ -16,44 +16,41 @@ */ package org.apache.dolphinscheduler.alert.runner; -import org.apache.dolphinscheduler.alert.manager.EmailManager; -import org.apache.dolphinscheduler.alert.manager.EnterpriseWeChatManager; import org.apache.dolphinscheduler.alert.utils.Constants; -import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils; import org.apache.dolphinscheduler.common.enums.AlertStatus; -import org.apache.dolphinscheduler.common.enums.AlertType; -import org.apache.dolphinscheduler.common.utils.CollectionUtils; -import org.apache.dolphinscheduler.common.utils.StringUtils; +import org.apache.dolphinscheduler.common.plugin.PluginManager; import org.apache.dolphinscheduler.dao.AlertDao; import org.apache.dolphinscheduler.dao.entity.Alert; import org.apache.dolphinscheduler.dao.entity.User; +import org.apache.dolphinscheduler.plugin.api.AlertPlugin; +import org.apache.dolphinscheduler.plugin.model.AlertData; +import org.apache.dolphinscheduler.plugin.model.AlertInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; /** * alert sender */ -public class AlertSender{ +public class AlertSender { private static final Logger logger = LoggerFactory.getLogger(AlertSender.class); - private static final EmailManager emailManager= new EmailManager(); - private static final EnterpriseWeChatManager weChatManager= new EnterpriseWeChatManager(); - - private List alertList; private AlertDao alertDao; + private PluginManager pluginManager; - public AlertSender(){} - public AlertSender(List alertList, AlertDao alertDao){ + public AlertSender() { + } + + public AlertSender(List alertList, AlertDao alertDao, PluginManager pluginManager) { super(); this.alertList = alertList; this.alertDao = alertDao; + this.pluginManager = pluginManager; } public void run() { @@ -61,92 +58,53 @@ public class AlertSender{ List users; Map retMaps = null; - for(Alert alert:alertList){ + for (Alert alert : alertList) { users = alertDao.listUserByAlertgroupId(alert.getAlertGroupId()); // receiving group list List receviersList = new ArrayList<>(); - for(User user:users){ + for (User user : users) { receviersList.add(user.getEmail()); } - // custom receiver - String receivers = alert.getReceivers(); - if (StringUtils.isNotEmpty(receivers)){ - String[] splits = receivers.split(","); - receviersList.addAll(Arrays.asList(splits)); - } - // copy list - List receviersCcList = new ArrayList<>(); + AlertData alertData = new AlertData(); + alertData.setId(alert.getId()) + .setAlertGroupId(alert.getAlertGroupId()) + .setContent(alert.getContent()) + .setLog(alert.getLog()) + .setReceivers(alert.getReceivers()) + .setReceiversCc(alert.getReceiversCc()) + .setShowType(alert.getShowType().getDescp()) + .setTitle(alert.getTitle()); + AlertInfo alertInfo = new AlertInfo(); + alertInfo.setAlertData(alertData); - // Custom Copier - String receiversCc = alert.getReceiversCc(); - - if (StringUtils.isNotEmpty(receiversCc)){ - String[] splits = receiversCc.split(","); - receviersCcList.addAll(Arrays.asList(splits)); - } - - if (CollectionUtils.isEmpty(receviersList) && CollectionUtils.isEmpty(receviersCcList)) { - logger.warn("alert send error : At least one receiver address required"); - alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE, "execution failure,At least one receiver address required.", alert.getId()); - continue; - } + alertInfo.addProp("receivers", receviersList); - if (alert.getAlertType() == AlertType.EMAIL){ - retMaps = emailManager.send(receviersList,receviersCcList, alert.getTitle(), alert.getContent(),alert.getShowType()); + AlertPlugin emailPlugin = pluginManager.findOne(Constants.PLUGIN_DEFAULT_EMAIL); + retMaps = emailPlugin.process(alertInfo); - alert.setInfo(retMaps); - }else if (alert.getAlertType() == AlertType.SMS){ - retMaps = emailManager.send(getReciversForSMS(users), alert.getTitle(), alert.getContent(),alert.getShowType()); - alert.setInfo(retMaps); + if (retMaps == null || !Boolean.parseBoolean(String.valueOf(retMaps.get(Constants.STATUS)))) { + alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE, String.valueOf(retMaps.get(Constants.MESSAGE)), alert.getId()); + logger.info("alert send error : {}", retMaps.get(Constants.MESSAGE)); } else { - logger.error("AlertType is not defined. code: {}, descp: {}", - alert.getAlertType().getCode(), - alert.getAlertType().getDescp()); - return; - } - - //send flag - boolean flag = false; - - if (null != retMaps) { - flag = Boolean.parseBoolean(String.valueOf(retMaps.get(Constants.STATUS))); - } - - if (flag) { - alertDao.updateAlert(AlertStatus.EXECUTION_SUCCESS, "execution success", alert.getId()); + alertDao.updateAlert(AlertStatus.EXECUTION_SUCCESS, (String) retMaps.get(Constants.MESSAGE), alert.getId()); logger.info("alert send success"); - if (EnterpriseWeChatUtils.isEnable()) { - logger.info("Enterprise WeChat is enable!"); - try { - String token = EnterpriseWeChatUtils.getToken(); - weChatManager.send(alert, token); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - } - - } else { - if (null != retMaps) { - alertDao.updateAlert(AlertStatus.EXECUTION_FAILURE, String.valueOf(retMaps.get(Constants.MESSAGE)), alert.getId()); - logger.info("alert send error : {}", retMaps.get(Constants.MESSAGE)); - } } } } - /** * get a list of SMS users + * * @param users * @return */ - private List getReciversForSMS(List users){ + private List getReciversForSMS(List users) { List list = new ArrayList<>(); - for (User user : users){ + for (User user : users) { list.add(user.getPhone()); } return list; diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java index 28be8aa195..8fa38c62fc 100644 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java +++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/Constants.java @@ -156,4 +156,21 @@ public class Constants { public static final String ENTERPRISE_WECHAT_AGENT_ID = "enterprise.wechat.agent.id"; public static final String ENTERPRISE_WECHAT_USERS = "enterprise.wechat.users"; + + /** + * plugin config + */ + public static final String PLUGIN_DIR = "plugin.dir"; + + public static final String PLUGIN_DEFAULT_EMAIL = "email"; + + public static final String PLUGIN_DEFAULT_EMAIL_CH = "邮件"; + + public static final String PLUGIN_DEFAULT_EMAIL_EN = "email"; + + public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERS = "receivers"; + + public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERCCS = "receiverCcs"; + + public static final String RETMAP_MSG = "msg"; } 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 index 170c0dd37e..4613adaa55 100644 --- 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 @@ -22,6 +22,7 @@ import org.apache.dolphinscheduler.dao.entity.Alert; import com.alibaba.fastjson.JSON; import com.google.common.reflect.TypeToken; +import org.apache.dolphinscheduler.plugin.model.AlertData; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -253,14 +254,13 @@ public class EnterpriseWeChatUtils { /** * Determine the mardown style based on the show type of the alert - * @param alert the alert * @return the markdown alert table/text */ - public static String markdownByAlert(Alert alert){ + public static String markdownByAlert(AlertData alert){ String result = ""; - if (alert.getShowType() == ShowType.TABLE) { + if (alert.getShowType().equals(ShowType.TABLE.getDescp())) { result = markdownTable(alert.getTitle(),alert.getContent()); - }else if(alert.getShowType() == ShowType.TEXT){ + }else if(alert.getShowType().equals(ShowType.TEXT.getDescp())){ result = markdownText(alert.getTitle(),alert.getContent()); } return result; diff --git a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java index ef364cb1c2..bb565f5133 100644 --- a/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java +++ b/dolphinscheduler-alert/src/main/java/org/apache/dolphinscheduler/alert/utils/MailUtils.java @@ -74,7 +74,7 @@ public class MailUtils { * @param showType the show type * @return the result map */ - public static Map sendMails(Collection receivers, String title, String content,ShowType showType) { + public static Map sendMails(Collection receivers, String title, String content,String showType) { return sendMails(receivers, null, title, content, showType); } @@ -87,7 +87,7 @@ public class MailUtils { * @param showType the show type * @return the send result */ - public static Map sendMails(Collection receivers, Collection receiversCc, String title, String content, ShowType showType) { + public static Map sendMails(Collection receivers, Collection receiversCc, String title, String content, String showType) { Map retMap = new HashMap<>(); retMap.put(Constants.STATUS, false); @@ -98,7 +98,7 @@ public class MailUtils { receivers.removeIf(StringUtils::isEmpty); - if (showType == ShowType.TABLE || showType == ShowType.TEXT){ + if (showType.equals(ShowType.TABLE.getDescp()) || showType.equals(ShowType.TEXT.getDescp())) { // send email HtmlEmail email = new HtmlEmail(); @@ -125,10 +125,10 @@ public class MailUtils { } catch (Exception e) { handleException(receivers, retMap, e); } - }else if (showType == ShowType.ATTACHMENT || showType == ShowType.TABLEATTACHMENT){ + }else if (showType.equals(ShowType.ATTACHMENT.getDescp()) || showType.equals(ShowType.TABLEATTACHMENT.getDescp())) { try { - String partContent = (showType == ShowType.ATTACHMENT ? "Please see the attachment " + title + Constants.EXCEL_SUFFIX_XLS : htmlTable(content,false)); + String partContent = (showType.equals(ShowType.ATTACHMENT.getDescp()) ? "Please see the attachment " + title + Constants.EXCEL_SUFFIX_XLS : htmlTable(content,false)); attachment(receivers,receiversCc,title,content,partContent); @@ -290,7 +290,7 @@ public class MailUtils { * @return the result map * @throws EmailException */ - private static Map getStringObjectMap(String title, String content, ShowType showType, Map retMap, HtmlEmail email) throws EmailException { + private static Map getStringObjectMap(String title, String content, String showType, Map retMap, HtmlEmail email) throws EmailException { /** * the subject of the message to be sent @@ -299,9 +299,9 @@ public class MailUtils { /** * to send information, you can use HTML tags in mail content because of the use of HtmlEmail */ - if (showType == ShowType.TABLE) { + if (showType.equals(ShowType.TABLE.getDescp())) { email.setMsg(htmlTable(content)); - } else if (showType == ShowType.TEXT) { + } else if (showType.equals(ShowType.TEXT.getDescp())) { email.setMsg(htmlText(content)); } diff --git a/dolphinscheduler-alert/src/main/resources/alert.properties b/dolphinscheduler-alert/src/main/resources/alert.properties index 3e83c01235..19b55fec97 100644 --- a/dolphinscheduler-alert/src/main/resources/alert.properties +++ b/dolphinscheduler-alert/src/main/resources/alert.properties @@ -45,5 +45,5 @@ enterprise.wechat.enable=false #enterprise.wechat.team.send.msg={\"toparty\":\"$toParty\",\"agentid\":\"$agentId\",\"msgtype\":\"text\",\"text\":{\"content\":\"$msg\"},\"safe\":\"0\"} #enterprise.wechat.user.send.msg={\"touser\":\"$toUser\",\"agentid\":\"$agentId\",\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"$msg\"}} - +plugin.dir=/Users/xx/your/path/to/plugin/dir diff --git a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPluginTest.java b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPluginTest.java new file mode 100644 index 0000000000..6c1f2f6d0d --- /dev/null +++ b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/plugin/EmailAlertPluginTest.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dolphinscheduler.alert.plugin; + +import org.apache.dolphinscheduler.alert.utils.Constants; +import org.apache.dolphinscheduler.common.enums.ShowType; +import org.apache.dolphinscheduler.plugin.api.AlertPlugin; +import org.apache.dolphinscheduler.plugin.model.AlertData; +import org.apache.dolphinscheduler.plugin.model.AlertInfo; +import org.apache.dolphinscheduler.plugin.model.PluginName; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.*; + +public class EmailAlertPluginTest { + + private static final Logger logger = LoggerFactory.getLogger(EmailAlertPluginTest.class); + + private AlertPlugin plugin; + + @Before + public void before() { + plugin = new EmailAlertPlugin(); + } + + @Test + public void getId() { + String id = plugin.getId(); + assertEquals(Constants.PLUGIN_DEFAULT_EMAIL, id); + } + + @Test + public void getName() { + PluginName pluginName = plugin.getName(); + assertEquals(Constants.PLUGIN_DEFAULT_EMAIL_CH, pluginName.getChinese()); + assertEquals(Constants.PLUGIN_DEFAULT_EMAIL_EN, pluginName.getEnglish()); + } + + @Test + public void process() { + AlertInfo alertInfo = new AlertInfo(); + AlertData alertData = new AlertData(); + alertData.setId(1) + .setAlertGroupId(1) + .setContent("[\"alarm time:2018-02-05\", \"service name:MYSQL_ALTER\", \"alarm name:MYSQL_ALTER_DUMP\", " + + "\"get the alarm exception.!,interface error,exception information:timed out\", \"request address:http://blog.csdn.net/dreamInTheWorld/article/details/78539286\"]") + .setLog("test log") + .setReceivers("bitace@163.com") + .setReceiversCc("bitace@163.com") + .setShowType(ShowType.TEXT.getDescp()) + .setTitle("test title"); + + alertInfo.setAlertData(alertData); + List list = new ArrayList(){{ add("bitace@163.com"); }}; + alertInfo.addProp("receivers", list); + plugin.process(alertInfo); + } +} \ No newline at end of file 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 index d0f3538c1b..2b405cc436 100644 --- 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 @@ -20,6 +20,7 @@ import com.alibaba.fastjson.JSON; import org.apache.dolphinscheduler.common.enums.AlertType; import org.apache.dolphinscheduler.common.enums.ShowType; import org.apache.dolphinscheduler.dao.entity.Alert; +import org.apache.dolphinscheduler.plugin.model.AlertData; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; @@ -120,14 +121,22 @@ public class EnterpriseWeChatUtilsTest { @Test public void testMarkdownByAlertForText(){ Alert alertForText = createAlertForText(); - String result = EnterpriseWeChatUtils.markdownByAlert(alertForText); + AlertData alertData = new AlertData(); + alertData.setTitle(alertForText.getTitle()) + .setShowType(alertForText.getShowType().getDescp()) + .setContent(alertForText.getContent()); + String result = EnterpriseWeChatUtils.markdownByAlert(alertData); Assert.assertNotNull(result); } @Test public void testMarkdownByAlertForTable(){ Alert alertForText = createAlertForTable(); - String result = EnterpriseWeChatUtils.markdownByAlert(alertForText); + AlertData alertData = new AlertData(); + alertData.setTitle(alertForText.getTitle()) + .setShowType(alertForText.getShowType().getDescp()) + .setContent(alertForText.getContent()); + String result = EnterpriseWeChatUtils.markdownByAlert(alertData); Assert.assertNotNull(result); } diff --git a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java index 1820a1ef89..11322da0e3 100644 --- a/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java +++ b/dolphinscheduler-alert/src/test/java/org/apache/dolphinscheduler/alert/utils/MailUtilsTest.java @@ -58,7 +58,7 @@ public class MailUtilsTest { alert.setAlertType(AlertType.EMAIL); alert.setAlertGroupId(4); - MailUtils.sendMails(Arrays.asList(receivers),Arrays.asList(receiversCc),alert.getTitle(),alert.getContent(), ShowType.TEXT); + MailUtils.sendMails(Arrays.asList(receivers),Arrays.asList(receiversCc),alert.getTitle(),alert.getContent(), ShowType.TEXT.getDescp()); } @@ -70,7 +70,7 @@ public class MailUtilsTest { String[] mails = new String[]{"xx@xx.com"}; for(Alert alert : alerts){ - MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), alert.getShowType()); + MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE.getDescp()); } } @@ -111,7 +111,7 @@ public class MailUtilsTest { alert.setContent(content); alert.setAlertType(AlertType.EMAIL); alert.setAlertGroupId(1); - MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE); + MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE.getDescp()); } /** @@ -170,7 +170,7 @@ public class MailUtilsTest { alert.setContent(content); alert.setAlertType(AlertType.EMAIL); alert.setAlertGroupId(1); - MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.ATTACHMENT); + MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.ATTACHMENT.getDescp()); } @Test @@ -183,7 +183,7 @@ public class MailUtilsTest { alert.setContent(content); alert.setAlertType(AlertType.EMAIL); alert.setAlertGroupId(1); - MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.TABLEATTACHMENT); + MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.TABLEATTACHMENT.getDescp()); } } diff --git a/dolphinscheduler-common/pom.xml b/dolphinscheduler-common/pom.xml index ca75a84a62..3954159dfa 100644 --- a/dolphinscheduler-common/pom.xml +++ b/dolphinscheduler-common/pom.xml @@ -32,12 +32,15 @@ 3.1.0 + + org.apache.dolphinscheduler + dolphinscheduler-plugin-api + com.alibaba fastjson compile - org.apache.httpcomponents httpclient diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java index 853ab95d1c..effa4f0f8e 100644 --- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java @@ -954,4 +954,11 @@ public final class Constants { * authorize readable perm */ public static final int AUTHORIZE_READABLE_PERM=4; + + + /** + * plugin configurations + */ + public static final String PLUGIN_JAR_SUFFIX = ".jar"; + } diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/FilePluginManager.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/FilePluginManager.java new file mode 100644 index 0000000000..1a260f25cd --- /dev/null +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/FilePluginManager.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.common.plugin; + +import org.apache.dolphinscheduler.common.Constants; +import org.apache.dolphinscheduler.plugin.api.AlertPlugin; +import org.apache.dolphinscheduler.plugin.spi.AlertPluginProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.concurrent.ConcurrentHashMap; + +/** + * FilePluginManager + */ +public class FilePluginManager implements PluginManager { + + private static final Logger logger = LoggerFactory.getLogger(FilePluginManager.class); + + private Map pluginMap = new ConcurrentHashMap<>(); + + private Map> pluginLoaderMap = new ConcurrentHashMap<>(); + + private Map classLoaderMap = new ConcurrentHashMap<>(); + + public FilePluginManager(String dirPath, String[] whitePrefixes, String[] excludePrefixes) throws MalformedURLException { + logger.info("start to load jar files in {}", dirPath); + File[] files = new File(dirPath).listFiles(); + if (files == null) { + logger.error("not a valid path - {}", dirPath); + System.exit(1); + } + for (File file : files) { + if (file.isDirectory() && !file.getPath().endsWith(Constants.PLUGIN_JAR_SUFFIX)) { + continue; + } + String pluginName = file.getName() + .substring(0, file.getName().length() - Constants.PLUGIN_JAR_SUFFIX.length()); + URL[] urls = new URL[]{ file.toURI().toURL() }; + PluginClassLoader classLoader = + new PluginClassLoader(urls, Thread.currentThread().getContextClassLoader(), whitePrefixes, excludePrefixes); + classLoaderMap.put(pluginName, classLoader); + + ServiceLoader loader = ServiceLoader.load(AlertPluginProvider.class, classLoader); + pluginLoaderMap.put(pluginName, loader); + + loader.forEach(provider -> { + AlertPlugin plugin = provider.createPlugin(); + pluginMap.put(plugin.getId(), plugin); + logger.info("loaded plugin - {}", plugin.getId()); + }); + } + } + + @Override + public AlertPlugin findOne(String name) { + return pluginMap.get(name); + } + + @Override + public Map findAll() { + return pluginMap; + } + + @Override + public void addPlugin(AlertPlugin plugin) { + pluginMap.put(plugin.getId(), plugin); + } + +} diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginClassLoader.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginClassLoader.java new file mode 100644 index 0000000000..8579e1cd96 --- /dev/null +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginClassLoader.java @@ -0,0 +1,134 @@ +package org.apache.dolphinscheduler.common.plugin; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * Plugin Class Loader + */ +public class PluginClassLoader extends URLClassLoader { + + private static final Logger logger = LoggerFactory.getLogger(PluginClassLoader.class); + + private static final String JAVA_PACKAGE_PREFIX = "java."; + private static final String JAVAX_PACKAGE_PREFIX = "javax."; + + private final String[] whitePrefixes; + + private final String[] excludePrefixes; + + public PluginClassLoader(URL[] urls, ClassLoader parent, String[] whitePrefix, String[] excludePreifx) { + super(urls, parent); + this.whitePrefixes = whitePrefix; + this.excludePrefixes = excludePreifx; + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + logger.trace("Received request to load class '{}'", name); + synchronized (getClassLoadingLock(name)) { + if (name.startsWith(JAVA_PACKAGE_PREFIX) || name.startsWith(JAVAX_PACKAGE_PREFIX)) { + return findSystemClass(name); + } + + boolean isWhitePrefixes = fromWhitePrefix(name); + boolean isExcludePrefixed = fromExcludePrefix(name); + + // if the class is part of the plugin engine use parent class loader + if (!isWhitePrefixes && isExcludePrefixed) { + return getParent().loadClass(name); + } + + // check whether it's already been loaded + Class loadedClass = findLoadedClass(name); + if (loadedClass != null) { + logger.debug("Found loaded class '{}'", name); + return loadedClass; + } + + // nope, try to load locally + try { + loadedClass = findClass(name); + logger.debug("Found class '{}' in plugin classpath", name); + return loadedClass; + } catch (ClassNotFoundException e) { + // try next step + } + + // use the standard ClassLoader (which follows normal parent delegation) + return super.loadClass(name); + } + } + + private boolean fromWhitePrefix(String name) { + for (String whitePrefix : this.whitePrefixes) { + if (name.startsWith(whitePrefix)) { + return true; + } + } + return false; + } + + private boolean fromExcludePrefix(String name) { + for (String excludePrefix : this.excludePrefixes) { + if (name.startsWith(excludePrefix)) { + return true; + } + } + return false; + } + + @Override + public Enumeration getResources(String name) throws IOException { + List allRes = new LinkedList<>(); + + Enumeration thisRes = findResources(name); + if (thisRes != null) { + while (thisRes.hasMoreElements()) { + allRes.add(thisRes.nextElement()); + } + } + + Enumeration parentRes = super.findResources(name); + if (parentRes != null) { + while (parentRes.hasMoreElements()) { + allRes.add(parentRes.nextElement()); + } + } + + return new Enumeration() { + Iterator it = allRes.iterator(); + + @Override + public boolean hasMoreElements() { + return it.hasNext(); + } + + @Override + public URL nextElement() { + return it.next(); + } + }; + } + + @Override + public URL getResource(String name) { + URL res = null; + + if (res == null) { + res = findResource(name); + } + if (res == null) { + res = super.getResource(name); + } + return res; + } +} diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginManager.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginManager.java new file mode 100644 index 0000000000..f8078841e4 --- /dev/null +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/plugin/PluginManager.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dolphinscheduler.common.plugin; + +import org.apache.dolphinscheduler.plugin.api.AlertPlugin; + +import java.util.Map; + +/** + * PluginManager + */ +public interface PluginManager { + + AlertPlugin findOne(String name); + + Map findAll(); + + void addPlugin(AlertPlugin plugin); +} diff --git a/dolphinscheduler-plugin-api/pom.xml b/dolphinscheduler-plugin-api/pom.xml new file mode 100644 index 0000000000..54160ea720 --- /dev/null +++ b/dolphinscheduler-plugin-api/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + org.apache.dolphinscheduler + dolphinscheduler + 1.2.1-SNAPSHOT + + dolphinscheduler-plugin-api + ${project.artifactId} + jar + + + UTF-8 + + + + + org.slf4j + slf4j-api + + + junit + junit + test + + + commons-io + commons-io + + + + diff --git a/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/api/AlertPlugin.java b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/api/AlertPlugin.java new file mode 100644 index 0000000000..deb7ff6aa4 --- /dev/null +++ b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/api/AlertPlugin.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dolphinscheduler.plugin.api; + +import org.apache.dolphinscheduler.plugin.model.AlertInfo; +import org.apache.dolphinscheduler.plugin.model.PluginName; + +import java.util.Map; + +/** + * Plugin + */ +public interface AlertPlugin { + + /** + * Get alert plugin id + * + * @return alert plugin id, which should be unique + */ + String getId(); + + /** + * Get alert plugin name, which will show in front end portal + * + * @return plugin name + */ + PluginName getName(); + + Map process(AlertInfo info); + +} diff --git a/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertData.java b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertData.java new file mode 100644 index 0000000000..4a277b509c --- /dev/null +++ b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertData.java @@ -0,0 +1,125 @@ +package org.apache.dolphinscheduler.plugin.model; + +/** + * AlertData + */ +public class AlertData { + + /** + * alert primary key + */ + private int id; + /** + * title + */ + private String title; + /** + * content + */ + private String content; + /** + * log + */ + private String log; + /** + * alertgroup_id + */ + private int alertGroupId; + /** + * receivers + */ + private String receivers; + /** + * show_type + */ + private String showType; + /** + * receivers_cc + */ + private String receiversCc; + + public AlertData() { + } + + public int getId() { + return id; + } + + public AlertData setId(int id) { + this.id = id; + return this; + } + + public String getTitle() { + return title; + } + + public AlertData setTitle(String title) { + this.title = title; + return this; + } + + public String getContent() { + return content; + } + + public AlertData setContent(String content) { + this.content = content; + return this; + } + + public String getLog() { + return log; + } + + public AlertData setLog(String log) { + this.log = log; + return this; + } + + public int getAlertGroupId() { + return alertGroupId; + } + + public AlertData setAlertGroupId(int alertGroupId) { + this.alertGroupId = alertGroupId; + return this; + } + + public String getReceivers() { + return receivers; + } + + public AlertData setReceivers(String receivers) { + this.receivers = receivers; + return this; + } + + public String getReceiversCc() { + return receiversCc; + } + + public AlertData setReceiversCc(String receiversCc) { + this.receiversCc = receiversCc; + return this; + } + + public String getShowType() { + return showType; + } + + public AlertData setShowType(String showType) { + this.showType = showType; + return this; + } + + public AlertData(int id, String title, String content, String log, int alertGroupId, String receivers, String receiversCc) { + this.id = id; + this.title = title; + this.content = content; + this.log = log; + this.alertGroupId = alertGroupId; + this.receivers = receivers; + this.receiversCc = receiversCc; + } +} diff --git a/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertInfo.java b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertInfo.java new file mode 100644 index 0000000000..1d71ed7d8a --- /dev/null +++ b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/AlertInfo.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dolphinscheduler.plugin.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * AlertInfo + */ +public class AlertInfo { + + private Map alertProps; + + private AlertData alertData; + + public AlertInfo() { + this.alertProps = new HashMap<>(); + } + + public Map getAlertProps() { + return alertProps; + } + + public AlertInfo setAlertProps(Map alertProps) { + this.alertProps = alertProps; + return this; + } + + public AlertInfo addProp(String key, Object value) { + this.alertProps.put(key, value); + return this; + } + + public Object getProp(String key) { + return this.alertProps.get(key); + } + + public AlertData getAlertData() { + return alertData; + } + + public AlertInfo setAlertData(AlertData alertData) { + this.alertData = alertData; + return this; + } +} diff --git a/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/PluginName.java b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/PluginName.java new file mode 100644 index 0000000000..8066e45f1d --- /dev/null +++ b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/model/PluginName.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dolphinscheduler.plugin.model; + +/** + * PluginName + */ +public class PluginName { + + private String chinese; + + private String english; + + public String getChinese() { + return chinese; + } + + public PluginName setChinese(String chinese) { + this.chinese = chinese; + return this; + } + + public String getEnglish() { + return english; + } + + public PluginName setEnglish(String english) { + this.english = english; + return this; + } +} diff --git a/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/spi/AlertPluginProvider.java b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/spi/AlertPluginProvider.java new file mode 100644 index 0000000000..594636f4eb --- /dev/null +++ b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/spi/AlertPluginProvider.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dolphinscheduler.plugin.spi; + +import org.apache.dolphinscheduler.plugin.api.AlertPlugin; + +/** + * PluginProvider + */ +public interface AlertPluginProvider { + + /** + * create an alert plugin + * + * @return an alert plugin + */ + AlertPlugin createPlugin(); + +} diff --git a/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtils.java b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtils.java new file mode 100644 index 0000000000..21970fddcb --- /dev/null +++ b/dolphinscheduler-plugin-api/src/main/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtils.java @@ -0,0 +1,232 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dolphinscheduler.plugin.utils; + +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * property utils + * single instance + */ +public class PropertyUtils { + + /** + * logger + */ + private static final Logger logger = LoggerFactory.getLogger(PropertyUtils.class); + + private static final Properties properties = new Properties(); + + private PropertyUtils() { + throw new IllegalStateException("PropertyUtils class"); + } + + static { + String[] propertyFiles = new String[]{"/plugin.properties"}; + for (String fileName : propertyFiles) { + InputStream fis = null; + try { + fis = PropertyUtils.class.getResourceAsStream(fileName); + properties.load(fis); + + } catch (IOException e) { + logger.error(e.getMessage(), e); + if (fis != null) { + IOUtils.closeQuietly(fis); + } + System.exit(1); + } finally { + IOUtils.closeQuietly(fis); + } + } + } + + /** + * get property value + * + * @param key property name + * @return property value + */ + public static String getString(String key) { + if (key == null) { + return null; + } + return properties.getProperty(key.trim()); + } + + /** + * get property value + * + * @param key property name + * @param defaultVal default value + * @return property value + */ + public static String getString(String key, String defaultVal) { + String val = properties.getProperty(key.trim()); + return val == null ? defaultVal : val; + } + + /** + * get property value + * + * @param key property name + * @return get property int value , if key == null, then return -1 + */ + public static int getInt(String key) { + return getInt(key, -1); + } + + /** + * + * @param key key + * @param defaultValue default value + * @return property value + */ + public static int getInt(String key, int defaultValue) { + String value = getString(key); + if (value == null) { + return defaultValue; + } + + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + logger.info(e.getMessage(),e); + } + return defaultValue; + } + + /** + * get property value + * + * @param key property name + * @return property value + */ + public static boolean getBoolean(String key) { + String value = properties.getProperty(key.trim()); + if(null != value){ + return Boolean.parseBoolean(value); + } + + return false; + } + + /** + * get property value + * + * @param key property name + * @param defaultValue default value + * @return property value + */ + public static Boolean getBoolean(String key, boolean defaultValue) { + String value = properties.getProperty(key.trim()); + if(null != value){ + return Boolean.parseBoolean(value); + } + + return defaultValue; + } + + /** + * get property long value + * @param key key + * @param defaultVal default value + * @return property value + */ + public static long getLong(String key, long defaultVal) { + String val = getString(key); + return val == null ? defaultVal : Long.parseLong(val); + } + + /** + * + * @param key key + * @return property value + */ + public static long getLong(String key) { + return getLong(key,-1); + } + + /** + * + * @param key key + * @param defaultVal default value + * @return property value + */ + public static double getDouble(String key, double defaultVal) { + String val = getString(key); + return val == null ? defaultVal : Double.parseDouble(val); + } + + + /** + * get array + * @param key property name + * @param splitStr separator + * @return property value through array + */ + public static String[] getArray(String key, String splitStr) { + String value = getString(key); + if (value == null) { + return new String[0]; + } + try { + String[] propertyArray = value.split(splitStr); + return propertyArray; + } catch (NumberFormatException e) { + logger.info(e.getMessage(),e); + } + return new String[0]; + } + + /** + * + * @param key key + * @param type type + * @param defaultValue default value + * @param T + * @return get enum value + */ + public > T getEnum(String key, Class type, + T defaultValue) { + String val = getString(key); + return val == null ? defaultValue : Enum.valueOf(type, val); + } + + /** + * get all properties with specified prefix, like: fs. + * @param prefix prefix to search + * @return all properties with specified prefix + */ + public static Map getPrefixedProperties(String prefix) { + Map matchedProperties = new HashMap<>(); + for (String propName : properties.stringPropertyNames()) { + if (propName.startsWith(prefix)) { + matchedProperties.put(propName, properties.getProperty(propName)); + } + } + return matchedProperties; + } +} diff --git a/dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtilsTest.java b/dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtilsTest.java new file mode 100644 index 0000000000..2911cf7485 --- /dev/null +++ b/dolphinscheduler-plugin-api/src/test/java/org/apache/dolphinscheduler/plugin/utils/PropertyUtilsTest.java @@ -0,0 +1,67 @@ +package org.apache.dolphinscheduler.plugin.utils; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.*; + +public class PropertyUtilsTest { + + private static final Logger logger = LoggerFactory.getLogger(PropertyUtilsTest.class); + + /** + * Test getString + */ + @Test + public void testGetString() { + + String result = PropertyUtils.getString("test.string"); + logger.info(result); + assertEquals("teststring", result); + + //If key is null, then return null + result = PropertyUtils.getString(null); + assertNull(result); + } + + + /** + * Test getBoolean + */ + @Test + public void testGetBoolean() { + + //Expected true + Boolean result = PropertyUtils.getBoolean("test.true"); + assertTrue(result); + + //Expected false + result = PropertyUtils.getBoolean("test.false"); + assertFalse(result); + } + + /** + * Test getLong + */ + @Test + public void testGetLong() { + long result = PropertyUtils.getLong("test.long"); + assertSame(result, 100L); + } + + /** + * Test getDouble + */ + @Test + public void testGetDouble() { + + //If key is undefine in alert.properties, and there is a defaultval, then return defaultval + double result = PropertyUtils.getDouble("abc", 5.0); + assertEquals(result, 5.0, 0); + + result = PropertyUtils.getDouble("cba", 5.0); + assertEquals(3.1, result, 0.01); + } + +} \ No newline at end of file diff --git a/dolphinscheduler-plugin-api/src/test/resources/plugin.properties b/dolphinscheduler-plugin-api/src/test/resources/plugin.properties new file mode 100644 index 0000000000..b3151c72d7 --- /dev/null +++ b/dolphinscheduler-plugin-api/src/test/resources/plugin.properties @@ -0,0 +1,5 @@ +test.string=teststring +test.false=false +test.true=true +cba=3.1 +test.long=100 \ No newline at end of file diff --git a/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java b/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java index 84e4e54a50..ccd4bb2214 100644 --- a/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java +++ b/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java @@ -457,7 +457,7 @@ public class SqlTask extends AbstractTask { String showTypeName = sqlParameters.getShowType().replace(COMMA,"").trim(); if(EnumUtils.isValidEnum(ShowType.class,showTypeName)){ Map mailResult = MailUtils.sendMails(receviersList, - receviersCcList, title, content, ShowType.valueOf(showTypeName)); + receviersCcList, title, content, ShowType.valueOf(showTypeName).getDescp()); if(!(boolean) mailResult.get(STATUS)){ throw new RuntimeException("send mail failed!"); } diff --git a/pom.xml b/pom.xml index dad1e3696b..52339cd183 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - 4.0.0 @@ -205,6 +204,11 @@ dolphinscheduler-server ${project.version} + + org.apache.dolphinscheduler + dolphinscheduler-plugin-api + ${project.version} + org.apache.dolphinscheduler dolphinscheduler-common @@ -346,7 +350,7 @@ mysql mysql-connector-java ${mysql.connector.version} - test + com.h2database @@ -974,6 +978,7 @@ dolphinscheduler-dist dolphinscheduler-remote dolphinscheduler-service + dolphinscheduler-plugin-api - + \ No newline at end of file