feat: add plugin management for alert service
This commit is contained in:
parent
d629d38574
commit
85f3ac10a0
|
|
@ -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<Alert> 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class EmailManager {
|
|||
* @param showType the showType
|
||||
* @return the send result
|
||||
*/
|
||||
public Map<String,Object> send(List<String> receviersList,List<String> receviersCcList,String title,String content,ShowType showType){
|
||||
public Map<String,Object> send(List<String> receviersList,List<String> 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<String,Object> send(List<String> receviersList,String title,String content,ShowType showType){
|
||||
public Map<String,Object> send(List<String> receviersList,String title,String content,String showType){
|
||||
|
||||
return MailUtils.sendMails(receviersList,title, content, showType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<String,Object> send(Alert alert, String token){
|
||||
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 {}",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) {
|
||||
|
|
|
|||
|
|
@ -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<String, Object> process(AlertInfo info) {
|
||||
Map<String, Object> retMaps = new HashMap<>();
|
||||
|
||||
AlertData alert = info.getAlertData();
|
||||
|
||||
List<String> receviersList = (List<String>) 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<String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<Alert> alertList;
|
||||
private AlertDao alertDao;
|
||||
private PluginManager pluginManager;
|
||||
|
||||
public AlertSender(){}
|
||||
public AlertSender(List<Alert> alertList, AlertDao alertDao){
|
||||
public AlertSender() {
|
||||
}
|
||||
|
||||
public AlertSender(List<Alert> 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<User> users;
|
||||
|
||||
Map<String, Object> retMaps = null;
|
||||
for(Alert alert:alertList){
|
||||
for (Alert alert : alertList) {
|
||||
users = alertDao.listUserByAlertgroupId(alert.getAlertGroupId());
|
||||
|
||||
// receiving group list
|
||||
List<String> 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<String> 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();
|
||||
alertInfo.addProp("receivers", receviersList);
|
||||
|
||||
if (StringUtils.isNotEmpty(receiversCc)){
|
||||
String[] splits = receiversCc.split(",");
|
||||
receviersCcList.addAll(Arrays.asList(splits));
|
||||
}
|
||||
AlertPlugin emailPlugin = pluginManager.findOne(Constants.PLUGIN_DEFAULT_EMAIL);
|
||||
retMaps = emailPlugin.process(alertInfo);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (alert.getAlertType() == AlertType.EMAIL){
|
||||
retMaps = emailManager.send(receviersList,receviersCcList, alert.getTitle(), alert.getContent(),alert.getShowType());
|
||||
|
||||
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<String> getReciversForSMS(List<User> users){
|
||||
private List<String> getReciversForSMS(List<User> users) {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (User user : users){
|
||||
for (User user : users) {
|
||||
list.add(user.getPhone());
|
||||
}
|
||||
return list;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ public class MailUtils {
|
|||
* @param showType the show type
|
||||
* @return the result map
|
||||
*/
|
||||
public static Map<String,Object> sendMails(Collection<String> receivers, String title, String content,ShowType showType) {
|
||||
public static Map<String,Object> sendMails(Collection<String> 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<String,Object> sendMails(Collection<String> receivers, Collection<String> receiversCc, String title, String content, ShowType showType) {
|
||||
public static Map<String,Object> sendMails(Collection<String> receivers, Collection<String> receiversCc, String title, String content, String showType) {
|
||||
Map<String,Object> 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<String, Object> getStringObjectMap(String title, String content, ShowType showType, Map<String, Object> retMap, HtmlEmail email) throws EmailException {
|
||||
private static Map<String, Object> getStringObjectMap(String title, String content, String showType, Map<String, Object> 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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String> list = new ArrayList<String>(){{ add("bitace@163.com"); }};
|
||||
alertInfo.addProp("receivers", list);
|
||||
plugin.process(alertInfo);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,12 +32,15 @@
|
|||
<codehaus.janino.version>3.1.0</codehaus.janino.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-plugin-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<String, AlertPlugin> pluginMap = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, ServiceLoader<AlertPluginProvider>> pluginLoaderMap = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, PluginClassLoader> 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<AlertPluginProvider> 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<String, AlertPlugin> findAll() {
|
||||
return pluginMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlugin(AlertPlugin plugin) {
|
||||
pluginMap.put(plugin.getId(), plugin);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<URL> getResources(String name) throws IOException {
|
||||
List<URL> allRes = new LinkedList<>();
|
||||
|
||||
Enumeration<URL> thisRes = findResources(name);
|
||||
if (thisRes != null) {
|
||||
while (thisRes.hasMoreElements()) {
|
||||
allRes.add(thisRes.nextElement());
|
||||
}
|
||||
}
|
||||
|
||||
Enumeration<URL> parentRes = super.findResources(name);
|
||||
if (parentRes != null) {
|
||||
while (parentRes.hasMoreElements()) {
|
||||
allRes.add(parentRes.nextElement());
|
||||
}
|
||||
}
|
||||
|
||||
return new Enumeration<URL>() {
|
||||
Iterator<URL> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, AlertPlugin> findAll();
|
||||
|
||||
void addPlugin(AlertPlugin plugin);
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dolphinscheduler-plugin-api</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -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<String, Object> process(AlertInfo info);
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, Object> alertProps;
|
||||
|
||||
private AlertData alertData;
|
||||
|
||||
public AlertInfo() {
|
||||
this.alertProps = new HashMap<>();
|
||||
}
|
||||
|
||||
public Map<String, Object> getAlertProps() {
|
||||
return alertProps;
|
||||
}
|
||||
|
||||
public AlertInfo setAlertProps(Map<String, Object> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
@ -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> T
|
||||
* @return get enum value
|
||||
*/
|
||||
public <T extends Enum<T>> T getEnum(String key, Class<T> 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<String, String> getPrefixedProperties(String prefix) {
|
||||
Map<String, String> matchedProperties = new HashMap<>();
|
||||
for (String propName : properties.stringPropertyNames()) {
|
||||
if (propName.startsWith(prefix)) {
|
||||
matchedProperties.put(propName, properties.getProperty(propName));
|
||||
}
|
||||
}
|
||||
return matchedProperties;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
test.string=teststring
|
||||
test.false=false
|
||||
test.true=true
|
||||
cba=3.1
|
||||
test.long=100
|
||||
|
|
@ -457,7 +457,7 @@ public class SqlTask extends AbstractTask {
|
|||
String showTypeName = sqlParameters.getShowType().replace(COMMA,"").trim();
|
||||
if(EnumUtils.isValidEnum(ShowType.class,showTypeName)){
|
||||
Map<String, Object> 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!");
|
||||
}
|
||||
|
|
|
|||
11
pom.xml
11
pom.xml
|
|
@ -15,7 +15,6 @@
|
|||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
@ -205,6 +204,11 @@
|
|||
<artifactId>dolphinscheduler-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-plugin-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-common</artifactId>
|
||||
|
|
@ -346,7 +350,7 @@
|
|||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.connector.version}</version>
|
||||
<scope>test</scope>
|
||||
<!-- <scope>test</scope>-->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
|
|
@ -974,6 +978,7 @@
|
|||
<module>dolphinscheduler-dist</module>
|
||||
<module>dolphinscheduler-remote</module>
|
||||
<module>dolphinscheduler-service</module>
|
||||
<module>dolphinscheduler-plugin-api</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
Loading…
Reference in New Issue