Kirs
4 years ago
committed by
GitHub
237 changed files with 6087 additions and 12419 deletions
@ -1,25 +0,0 @@
|
||||
# |
||||
# Licensed to the Apache Software Foundation (ASF) under one or more |
||||
# contributor license agreements. See the NOTICE file distributed with |
||||
# this work for additional information regarding copyright ownership. |
||||
# The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
# (the "License"); you may not use this file except in compliance with |
||||
# the License. You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
# |
||||
dependencies: |
||||
- name: postgresql |
||||
version: 8.x.x |
||||
repository: https://charts.bitnami.com/bitnami |
||||
condition: postgresql.enabled |
||||
- name: zookeeper |
||||
version: 5.x.x |
||||
repository: https://charts.bitnami.com/bitnami |
||||
condition: redis.enabled |
@ -1,25 +0,0 @@
|
||||
# |
||||
# Licensed to the Apache Software Foundation (ASF) under one or more |
||||
# contributor license agreements. See the NOTICE file distributed with |
||||
# this work for additional information regarding copyright ownership. |
||||
# The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
# (the "License"); you may not use this file except in compliance with |
||||
# the License. You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
# |
||||
dependencies: |
||||
- name: postgresql |
||||
version: 8.x.x |
||||
repository: https://charts.bitnami.com/bitnami |
||||
condition: postgresql.enabled |
||||
- name: zookeeper |
||||
version: 5.x.x |
||||
repository: https://charts.bitnami.com/bitnami |
||||
condition: redis.enabled |
@ -1,82 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
<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"> |
||||
<parent> |
||||
<artifactId>dolphinscheduler-alert-plugin</artifactId> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<version>1.3.4-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-alert-dingtalk</artifactId> |
||||
<packaging>dolphinscheduler-plugin</packaging> |
||||
|
||||
<dependencies> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-spi</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.httpcomponents</groupId> |
||||
<artifactId>httpclient</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>ch.qos.logback</groupId> |
||||
<artifactId>logback-classic</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.slf4j</groupId> |
||||
<artifactId>slf4j-api</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-annotations</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>junit</groupId> |
||||
<artifactId>junit</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.mockito</groupId> |
||||
<artifactId>mockito-core</artifactId> |
||||
<type>jar</type> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
<build> |
||||
<finalName>dolphinscheduler-alert-dingtalk-${project.version}</finalName> |
||||
</build> |
||||
|
||||
</project> |
@ -1,41 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.dingtalk; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertData; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertInfo; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* DingTalkAlertChannel |
||||
*/ |
||||
public class DingTalkAlertChannel implements AlertChannel { |
||||
|
||||
@Override |
||||
public AlertResult process(AlertInfo alertInfo) { |
||||
|
||||
AlertData alertData = alertInfo.getAlertData(); |
||||
String alertParams = alertInfo.getAlertParams(); |
||||
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams); |
||||
return new DingTalkSender(paramsMap).sendDingTalkMsg(alertData.getTitle(), alertData.getContent()); |
||||
} |
||||
} |
@ -1,89 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.dingtalk; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
import org.apache.dolphinscheduler.spi.params.InputParam; |
||||
import org.apache.dolphinscheduler.spi.params.PasswordParam; |
||||
import org.apache.dolphinscheduler.spi.params.RadioParam; |
||||
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.params.base.Validate; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* DingTalkAlertChannelFactory |
||||
*/ |
||||
public class DingTalkAlertChannelFactory implements AlertChannelFactory { |
||||
@Override |
||||
public String getName() { |
||||
return "DingTalk"; |
||||
} |
||||
|
||||
@Override |
||||
public List<PluginParams> getParams() { |
||||
InputParam webHookParam = InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, DingTalkParamsConstants.DING_TALK_WEB_HOOK) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
InputParam keywordParam = InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, DingTalkParamsConstants.DING_TALK_KEYWORD) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
RadioParam isEnableProxy = |
||||
RadioParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE) |
||||
.addParamsOptions(new ParamsOptions("YES", true, false)) |
||||
.addParamsOptions(new ParamsOptions("NO", false, false)) |
||||
.setValue(true) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(false) |
||||
.build()) |
||||
.build(); |
||||
InputParam proxyParam = |
||||
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY, DingTalkParamsConstants.DING_TALK_PROXY) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(false).build()) |
||||
.build(); |
||||
|
||||
InputParam portParam = InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PORT, DingTalkParamsConstants.DING_TALK_PORT) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(false).build()) |
||||
.build(); |
||||
|
||||
InputParam userParam = |
||||
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_USER, DingTalkParamsConstants.DING_TALK_USER) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(false).build()) |
||||
.build(); |
||||
PasswordParam passwordParam = PasswordParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD, DingTalkParamsConstants.DING_TALK_PASSWORD) |
||||
.setPlaceholder("if enable use authentication, you need input password") |
||||
.build(); |
||||
|
||||
return Arrays.asList(webHookParam, keywordParam, isEnableProxy, proxyParam, portParam, userParam, passwordParam); |
||||
} |
||||
|
||||
@Override |
||||
public AlertChannel create() { |
||||
return new DingTalkAlertChannel(); |
||||
} |
||||
} |
@ -1,34 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.dingtalk; |
||||
|
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
|
||||
/** |
||||
* DingTalkAlertPlugin |
||||
*/ |
||||
public class DingTalkAlertPlugin implements DolphinSchedulerPlugin { |
||||
|
||||
@Override |
||||
public Iterable<AlertChannelFactory> getAlertChannelFactorys() { |
||||
return ImmutableList.of(new DingTalkAlertChannelFactory()); |
||||
} |
||||
} |
@ -1,57 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.dingtalk; |
||||
|
||||
/** |
||||
* DingTalkParamsConstants |
||||
*/ |
||||
public class DingTalkParamsConstants { |
||||
|
||||
public DingTalkParamsConstants() { |
||||
throw new IllegalStateException("Utility class"); |
||||
} |
||||
|
||||
static final String DING_TALK_WEB_HOOK = "dingtalk.webhook"; |
||||
|
||||
static final String NAME_DING_TALK_WEB_HOOK = "dingTalkWebHook"; |
||||
|
||||
static final String DING_TALK_KEYWORD = "dingtalk.keyword"; |
||||
|
||||
static final String NAME_DING_TALK_KEYWORD = "dingTalkKeyword"; |
||||
|
||||
public static final String DING_TALK_PROXY_ENABLE = "dingtalk.isEnableProxy"; |
||||
|
||||
static final String NAME_DING_TALK_PROXY_ENABLE = "dingTalkIsEnableProxy"; |
||||
|
||||
static final String DING_TALK_PROXY = "dingtalk.proxy"; |
||||
|
||||
static final String NAME_DING_TALK_PROXY = "dingTalkProxy"; |
||||
|
||||
static final String DING_TALK_PORT = "dingtalk.port"; |
||||
|
||||
static final String NAME_DING_TALK_PORT = "dingTalkPort"; |
||||
|
||||
static final String DING_TALK_USER = "dingtalk.user"; |
||||
|
||||
static final String NAME_DING_TALK_USER = "dingTalkUser"; |
||||
|
||||
static final String DING_TALK_PASSWORD = "dingtalk.password"; |
||||
|
||||
static final String NAME_DING_TALK_PASSWORD = "dingTalkPassword"; |
||||
|
||||
} |
@ -1,204 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.dingtalk; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import org.apache.commons.codec.binary.StringUtils; |
||||
import org.apache.http.HttpEntity; |
||||
import org.apache.http.HttpHost; |
||||
import org.apache.http.auth.AuthScope; |
||||
import org.apache.http.auth.UsernamePasswordCredentials; |
||||
import org.apache.http.client.CredentialsProvider; |
||||
import org.apache.http.client.config.RequestConfig; |
||||
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
import org.apache.http.client.methods.HttpPost; |
||||
import org.apache.http.entity.StringEntity; |
||||
import org.apache.http.impl.client.BasicCredentialsProvider; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.apache.http.impl.client.HttpClients; |
||||
import org.apache.http.util.EntityUtils; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* Ding Talk Sender |
||||
*/ |
||||
public class DingTalkSender { |
||||
private static final Logger logger = LoggerFactory.getLogger(DingTalkSender.class); |
||||
|
||||
private String url; |
||||
|
||||
private String keyword; |
||||
|
||||
private Boolean enableProxy; |
||||
|
||||
private String proxy; |
||||
|
||||
private Integer port; |
||||
|
||||
private String user; |
||||
|
||||
private String password; |
||||
|
||||
DingTalkSender(Map<String, String> config) { |
||||
url = config.get(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK); |
||||
keyword = config.get(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD); |
||||
enableProxy = Boolean.valueOf(config.get(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE)); |
||||
if (Boolean.TRUE.equals(enableProxy)) { |
||||
port = Integer.parseInt(config.get(DingTalkParamsConstants.NAME_DING_TALK_PORT)); |
||||
proxy = config.get(DingTalkParamsConstants.NAME_DING_TALK_PROXY); |
||||
user = config.get(DingTalkParamsConstants.DING_TALK_USER); |
||||
password = config.get(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD); |
||||
} |
||||
|
||||
} |
||||
|
||||
public AlertResult sendDingTalkMsg(String msg, String charset) { |
||||
AlertResult alertResult; |
||||
try { |
||||
String resp = sendMsg(msg, charset); |
||||
return checkSendDingTalkSendMsgResult(resp); |
||||
} catch (Exception e) { |
||||
logger.info("send ding talk alert msg exception : {}", e.getMessage()); |
||||
alertResult = new AlertResult(); |
||||
alertResult.setStatus("false"); |
||||
alertResult.setMessage("send ding talk alert fail."); |
||||
} |
||||
return alertResult; |
||||
} |
||||
|
||||
private String sendMsg(String msg, String charset) throws IOException { |
||||
|
||||
String msgToJson = textToJsonString(msg + "#" + keyword); |
||||
HttpPost httpPost = constructHttpPost(url, msgToJson, charset); |
||||
|
||||
CloseableHttpClient httpClient; |
||||
if (Boolean.TRUE.equals(enableProxy)) { |
||||
httpClient = getProxyClient(proxy, port, user, password); |
||||
RequestConfig rcf = getProxyConfig(proxy, port); |
||||
httpPost.setConfig(rcf); |
||||
} else { |
||||
httpClient = getDefaultClient(); |
||||
} |
||||
|
||||
try { |
||||
CloseableHttpResponse response = httpClient.execute(httpPost); |
||||
String resp; |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
resp = EntityUtils.toString(entity, charset); |
||||
EntityUtils.consume(entity); |
||||
} finally { |
||||
response.close(); |
||||
} |
||||
logger.info("Ding Talk send [ %s ], resp:{%s}", msg, resp); |
||||
return resp; |
||||
} finally { |
||||
httpClient.close(); |
||||
} |
||||
} |
||||
|
||||
private static HttpPost constructHttpPost(String url, String msg, String charset) { |
||||
HttpPost post = new HttpPost(url); |
||||
StringEntity entity = new StringEntity(msg, charset); |
||||
post.setEntity(entity); |
||||
post.addHeader("Content-Type", "application/json; charset=utf-8"); |
||||
return post; |
||||
} |
||||
|
||||
private static CloseableHttpClient getProxyClient(String proxy, int port, String user, String password) { |
||||
HttpHost httpProxy = new HttpHost(proxy, port); |
||||
CredentialsProvider provider = new BasicCredentialsProvider(); |
||||
provider.setCredentials(new AuthScope(httpProxy), new UsernamePasswordCredentials(user, password)); |
||||
return HttpClients.custom().setDefaultCredentialsProvider(provider).build(); |
||||
} |
||||
|
||||
private static CloseableHttpClient getDefaultClient() { |
||||
return HttpClients.createDefault(); |
||||
} |
||||
|
||||
private static RequestConfig getProxyConfig(String proxy, int port) { |
||||
HttpHost httpProxy = new HttpHost(proxy, port); |
||||
return RequestConfig.custom().setProxy(httpProxy).build(); |
||||
} |
||||
|
||||
private static String textToJsonString(String text) { |
||||
Map<String, Object> items = new HashMap<>(); |
||||
items.put("msgtype", "text"); |
||||
Map<String, String> textContent = new HashMap<>(); |
||||
byte[] byt = StringUtils.getBytesUtf8(text); |
||||
String txt = StringUtils.newStringUtf8(byt); |
||||
textContent.put("content", txt); |
||||
items.put("text", textContent); |
||||
return JSONUtils.toJsonString(items); |
||||
} |
||||
|
||||
public static class DingTalkSendMsgResponse { |
||||
private Integer errcode; |
||||
private String errmsg; |
||||
|
||||
public Integer getErrcode() { |
||||
return errcode; |
||||
} |
||||
|
||||
public void setErrcode(Integer errcode) { |
||||
this.errcode = errcode; |
||||
} |
||||
|
||||
public String getErrmsg() { |
||||
return errmsg; |
||||
} |
||||
|
||||
public void setErrmsg(String errmsg) { |
||||
this.errmsg = errmsg; |
||||
} |
||||
} |
||||
|
||||
private static AlertResult checkSendDingTalkSendMsgResult(String result) { |
||||
AlertResult alertResult = new AlertResult(); |
||||
alertResult.setStatus("false"); |
||||
|
||||
if (null == result) { |
||||
alertResult.setMessage("send ding talk msg error"); |
||||
logger.info("send ding talk msg error,ding talk server resp is null"); |
||||
return alertResult; |
||||
} |
||||
DingTalkSendMsgResponse sendMsgResponse = JSONUtils.parseObject(result, DingTalkSendMsgResponse.class); |
||||
if (null == sendMsgResponse) { |
||||
alertResult.setMessage("send ding talk msg fail"); |
||||
logger.info("send ding talk msg error,resp error"); |
||||
return alertResult; |
||||
} |
||||
if (sendMsgResponse.errcode == 0) { |
||||
alertResult.setStatus("true"); |
||||
alertResult.setMessage("send ding talk msg success"); |
||||
return alertResult; |
||||
} |
||||
alertResult.setMessage(String.format("alert send ding talk msg error : %s", sendMsgResponse.getErrmsg())); |
||||
logger.info("alert send ding talk msg error : {}", sendMsgResponse.getErrmsg()); |
||||
return alertResult; |
||||
} |
||||
|
||||
} |
@ -1,48 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.dingtalk; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* DingTalkAlertChannelFactoryTest |
||||
*/ |
||||
public class DingTalkAlertChannelFactoryTest { |
||||
|
||||
@Test |
||||
public void testGetParams() { |
||||
DingTalkAlertChannelFactory dingTalkAlertChannelFactory = new DingTalkAlertChannelFactory(); |
||||
List<PluginParams> params = dingTalkAlertChannelFactory.getParams(); |
||||
JSONUtils.toJsonString(params); |
||||
Assert.assertEquals(7, params.size()); |
||||
} |
||||
|
||||
@Test |
||||
public void testCreate() { |
||||
DingTalkAlertChannelFactory dingTalkAlertChannelFactory = new DingTalkAlertChannelFactory(); |
||||
AlertChannel alertChannel = dingTalkAlertChannelFactory.create(); |
||||
Assert.assertNotNull(alertChannel); |
||||
} |
||||
} |
@ -1,57 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.dingtalk; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* DingTalkSenderTest |
||||
*/ |
||||
public class DingTalkSenderTest { |
||||
|
||||
private static Map<String, String> dingTalkConfig = new HashMap<>(); |
||||
|
||||
@Before |
||||
public void initDingTalkConfig() { |
||||
|
||||
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, "keyWord"); |
||||
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, "url"); |
||||
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, "false"); |
||||
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD, "password"); |
||||
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PORT, "9988"); |
||||
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_USER, "user1,user2"); |
||||
} |
||||
|
||||
@Test |
||||
public void testSend() { |
||||
DingTalkSender dingTalkSender = new DingTalkSender(dingTalkConfig); |
||||
dingTalkSender.sendDingTalkMsg("keyWord+Welcome", "UTF-8"); |
||||
dingTalkConfig.put(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, "true"); |
||||
dingTalkSender = new DingTalkSender(dingTalkConfig); |
||||
AlertResult alertResult = dingTalkSender.sendDingTalkMsg("keyWord+Welcome", "UTF-8"); |
||||
Assert.assertEquals("false",alertResult.getStatus()); |
||||
} |
||||
|
||||
} |
@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
<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"> |
||||
<parent> |
||||
<artifactId>dolphinscheduler-alert-plugin</artifactId> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<version>1.3.4-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-alert-email</artifactId> |
||||
<!-- can be load as a Alert Plugin when development and run server in IDE --> |
||||
<packaging>dolphinscheduler-plugin</packaging> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-spi</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-annotations</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-databind</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.commons</groupId> |
||||
<artifactId>commons-collections4</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.poi</groupId> |
||||
<artifactId>poi</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>ch.qos.logback</groupId> |
||||
<artifactId>logback-classic</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.slf4j</groupId> |
||||
<artifactId>slf4j-api</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.commons</groupId> |
||||
<artifactId>commons-email</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-annotations</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-databind</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>junit</groupId> |
||||
<artifactId>junit</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.mockito</groupId> |
||||
<artifactId>mockito-core</artifactId> |
||||
<type>jar</type> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.powermock</groupId> |
||||
<artifactId>powermock-module-junit4</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.powermock</groupId> |
||||
<artifactId>powermock-api-mockito2</artifactId> |
||||
<scope>test</scope> |
||||
<exclusions> |
||||
<exclusion> |
||||
<groupId>org.mockito</groupId> |
||||
<artifactId>mockito-core</artifactId> |
||||
</exclusion> |
||||
</exclusions> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
<build> |
||||
<finalName>dolphinscheduler-alert-email-${project.version}</finalName> |
||||
</build> |
||||
|
||||
</project> |
@ -1,69 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertData; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertInfo; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* email alert channel . use email to seed the alertInfo |
||||
*/ |
||||
public class EmailAlertChannel implements AlertChannel { |
||||
private static final Logger logger = LoggerFactory.getLogger(EmailAlertChannel.class); |
||||
|
||||
@Override |
||||
public AlertResult process(AlertInfo info) { |
||||
|
||||
AlertData alert = info.getAlertData(); |
||||
String alertParams = info.getAlertParams(); |
||||
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams); |
||||
MailSender mailSender = new MailSender(paramsMap); |
||||
AlertResult alertResult = mailSender.sendMails(alert.getTitle(), alert.getContent()); |
||||
|
||||
//send flag
|
||||
boolean flag = false; |
||||
|
||||
if (alertResult == null) { |
||||
alertResult = new AlertResult(); |
||||
alertResult.setStatus("false"); |
||||
alertResult.setMessage("alert send error."); |
||||
logger.info("alert send error : {}", alertResult.getMessage()); |
||||
return alertResult; |
||||
} |
||||
|
||||
flag = Boolean.parseBoolean(String.valueOf(alertResult.getStatus())); |
||||
|
||||
if (flag) { |
||||
logger.info("alert send success"); |
||||
alertResult.setMessage("email send success."); |
||||
} else { |
||||
alertResult.setMessage("alert send error."); |
||||
logger.info("alert send error : {}", alertResult.getMessage()); |
||||
} |
||||
|
||||
return alertResult; |
||||
} |
||||
} |
@ -1,137 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertConstants; |
||||
import org.apache.dolphinscheduler.spi.alert.ShowType; |
||||
import org.apache.dolphinscheduler.spi.params.InputParam; |
||||
import org.apache.dolphinscheduler.spi.params.PasswordParam; |
||||
import org.apache.dolphinscheduler.spi.params.RadioParam; |
||||
import org.apache.dolphinscheduler.spi.params.base.DataType; |
||||
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.params.base.Validate; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* email alert factory |
||||
*/ |
||||
public class EmailAlertChannelFactory implements AlertChannelFactory { |
||||
@Override |
||||
public String getName() { |
||||
return "Email"; |
||||
} |
||||
|
||||
@Override |
||||
public List<PluginParams> getParams() { |
||||
|
||||
List<PluginParams> paramsList = new ArrayList<>(); |
||||
InputParam receivesParam = InputParam.newBuilder(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS, MailParamsConstants.PLUGIN_DEFAULT_EMAIL_RECEIVERS) |
||||
.setPlaceholder("please input receives") |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam receiveCcsParam = InputParam.newBuilder(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS, MailParamsConstants.PLUGIN_DEFAULT_EMAIL_RECEIVERCCS) |
||||
.build(); |
||||
|
||||
InputParam mailSmtpHost = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_HOST, MailParamsConstants.MAIL_SMTP_HOST) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
InputParam mailSmtpPort = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_PORT, MailParamsConstants.MAIL_SMTP_PORT) |
||||
.setValue(25) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.setType(DataType.NUMBER.getDataType()) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam mailSender = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_SENDER, MailParamsConstants.MAIL_SENDER) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
RadioParam enableSmtpAuth = RadioParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_AUTH, MailParamsConstants.MAIL_SMTP_AUTH) |
||||
.addParamsOptions(new ParamsOptions("YES", true, false)) |
||||
.addParamsOptions(new ParamsOptions("NO", false, false)) |
||||
.setValue(true) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
InputParam mailUser = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_USER, MailParamsConstants.MAIL_USER) |
||||
.setPlaceholder("if enable use authentication, you need input user") |
||||
.build(); |
||||
|
||||
PasswordParam mailPassword = PasswordParam.newBuilder(MailParamsConstants.NAME_MAIL_PASSWD, MailParamsConstants.MAIL_PASSWD) |
||||
.setPlaceholder("if enable use authentication, you need input password") |
||||
.build(); |
||||
|
||||
RadioParam enableTls = RadioParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_STARTTLS_ENABLE, MailParamsConstants.MAIL_SMTP_STARTTLS_ENABLE) |
||||
.addParamsOptions(new ParamsOptions("YES", true, false)) |
||||
.addParamsOptions(new ParamsOptions("NO", false, false)) |
||||
.setValue(false) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
RadioParam enableSsl = RadioParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_SSL_ENABLE, MailParamsConstants.MAIL_SMTP_SSL_ENABLE) |
||||
.addParamsOptions(new ParamsOptions("YES", true, false)) |
||||
.addParamsOptions(new ParamsOptions("NO", false, false)) |
||||
.setValue(false) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
InputParam sslTrust = InputParam.newBuilder(MailParamsConstants.NAME_MAIL_SMTP_SSL_TRUST, MailParamsConstants.MAIL_SMTP_SSL_TRUST) |
||||
.setValue("*") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
RadioParam showType = RadioParam.newBuilder(AlertConstants.SHOW_TYPE, AlertConstants.SHOW_TYPE) |
||||
.addParamsOptions(new ParamsOptions(ShowType.TABLE.getDescp(), ShowType.TABLE.getDescp(), false)) |
||||
.addParamsOptions(new ParamsOptions(ShowType.TEXT.getDescp(), ShowType.TEXT.getDescp(), false)) |
||||
.addParamsOptions(new ParamsOptions(ShowType.ATTACHMENT.getDescp(), ShowType.ATTACHMENT.getDescp(), false)) |
||||
.addParamsOptions(new ParamsOptions(ShowType.TABLEATTACHMENT.getDescp(), ShowType.TABLEATTACHMENT.getDescp(), false)) |
||||
.setValue(ShowType.TABLE.getDescp()) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
paramsList.add(receivesParam); |
||||
paramsList.add(receiveCcsParam); |
||||
paramsList.add(mailSmtpHost); |
||||
paramsList.add(mailSmtpPort); |
||||
paramsList.add(mailSender); |
||||
paramsList.add(enableSmtpAuth); |
||||
paramsList.add(mailUser); |
||||
paramsList.add(mailPassword); |
||||
paramsList.add(enableTls); |
||||
paramsList.add(enableSsl); |
||||
paramsList.add(sslTrust); |
||||
paramsList.add(showType); |
||||
|
||||
return paramsList; |
||||
} |
||||
|
||||
@Override |
||||
public AlertChannel create() { |
||||
return new EmailAlertChannel(); |
||||
} |
||||
} |
@ -1,33 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
|
||||
/** |
||||
* email alert plugin |
||||
*/ |
||||
public class EmailAlertPlugin implements DolphinSchedulerPlugin { |
||||
@Override |
||||
public Iterable<AlertChannelFactory> getAlertChannelFactorys() { |
||||
return ImmutableList.of(new EmailAlertChannelFactory()); |
||||
} |
||||
} |
@ -1,75 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
public class EmailConstants { |
||||
|
||||
|
||||
public static final String XLS_FILE_PATH = "xls.file.path"; |
||||
|
||||
public static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol"; |
||||
|
||||
public static final String DEFAULT_SMTP_PORT = "25"; |
||||
|
||||
public static final String TEXT_HTML_CHARSET_UTF_8 = "text/html;charset=utf-8"; |
||||
|
||||
public static final int NUMBER_1000 = 1000; |
||||
|
||||
public static final String TR = "<tr>"; |
||||
|
||||
public static final String TD = "<td>"; |
||||
|
||||
public static final String TD_END = "</td>"; |
||||
|
||||
public static final String TR_END = "</tr>"; |
||||
|
||||
public static final String TITLE = "title"; |
||||
|
||||
public static final String CONTENT = "content"; |
||||
|
||||
public static final String TH = "<th>"; |
||||
|
||||
public static final String TH_END = "</th>"; |
||||
|
||||
public static final String MARKDOWN_QUOTE = ">"; |
||||
|
||||
public static final String MARKDOWN_ENTER = "\n"; |
||||
|
||||
public static final String HTML_HEADER_PREFIX = new StringBuilder("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>") |
||||
.append("<html>") |
||||
.append("<head>") |
||||
.append("<title>dolphinscheduler</title>") |
||||
.append("<meta name='Keywords' content=''>") |
||||
.append("<meta name='Description' content=''>") |
||||
.append("<style type=\"text/css\">") |
||||
.append("table {margin-top:0px;padding-top:0px;border:1px solid;font-size: 14px;color: #333333;border-width: 1px;border-color: #666666;border-collapse: collapse;}") |
||||
.append("table th {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #dedede;text-align: left;}") |
||||
.append("table td {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #ffffff;text-align: left;}") |
||||
.append("</style>") |
||||
.append("</head>") |
||||
.append("<body style=\"margin:0;padding:0\"><table border=\"1px\" cellpadding=\"5px\" cellspacing=\"-10px\"> ") |
||||
.toString(); |
||||
|
||||
public static final String TABLE_BODY_HTML_TAIL = "</table></body></html>"; |
||||
|
||||
public static final String UTF_8 = "UTF-8"; |
||||
|
||||
public static final String EXCEL_SUFFIX_XLS = ".xls"; |
||||
|
||||
public static final String SINGLE_SLASH = "/"; |
||||
} |
@ -1,65 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
/** |
||||
* mail plugin params json use |
||||
*/ |
||||
public class MailParamsConstants { |
||||
|
||||
public MailParamsConstants() { |
||||
throw new IllegalStateException("Utility class"); |
||||
} |
||||
|
||||
public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERS = "$t('receivers')"; |
||||
public static final String NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS = "receivers"; |
||||
|
||||
public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERCCS = "$t('receiverCcs')"; |
||||
public static final String NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS = "receiverCcs"; |
||||
|
||||
public static final String MAIL_PROTOCOL = "transport.protocol"; |
||||
public static final String NAME_MAIL_PROTOCOL = "protocol"; |
||||
|
||||
public static final String MAIL_SMTP_HOST = "smtp.host"; |
||||
public static final String NAME_MAIL_SMTP_HOST = "serverHost"; |
||||
|
||||
public static final String MAIL_SMTP_PORT = "smtp.port"; |
||||
public static final String NAME_MAIL_SMTP_PORT = "serverPort"; |
||||
|
||||
public static final String MAIL_SENDER = "sender"; |
||||
public static final String NAME_MAIL_SENDER = "sender"; |
||||
|
||||
public static final String MAIL_SMTP_AUTH = "smtp.auth"; |
||||
public static final String NAME_MAIL_SMTP_AUTH = "enableSmtpAuth"; |
||||
|
||||
public static final String MAIL_USER = "user"; |
||||
public static final String NAME_MAIL_USER = "user"; |
||||
|
||||
public static final String MAIL_PASSWD = "passwd"; |
||||
public static final String NAME_MAIL_PASSWD = "passwd"; |
||||
|
||||
public static final String MAIL_SMTP_STARTTLS_ENABLE = "smtp.starttls.enable"; |
||||
public static final String NAME_MAIL_SMTP_STARTTLS_ENABLE = "starttlsEnable"; |
||||
|
||||
public static final String MAIL_SMTP_SSL_ENABLE = "smtp.ssl.enable"; |
||||
public static final String NAME_MAIL_SMTP_SSL_ENABLE = "sslEnable"; |
||||
|
||||
public static final String MAIL_SMTP_SSL_TRUST = "smtp.ssl.trust"; |
||||
public static final String NAME_MAIL_SMTP_SSL_TRUST = "smtpSslTrust"; |
||||
|
||||
} |
@ -1,429 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
import static java.util.Objects.requireNonNull; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.alert.email.template.AlertTemplate; |
||||
import org.apache.dolphinscheduler.plugin.alert.email.template.DefaultHTMLTemplate; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertConstants; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.alert.ShowType; |
||||
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||
|
||||
import org.apache.commons.collections4.CollectionUtils; |
||||
import org.apache.commons.mail.EmailException; |
||||
import org.apache.commons.mail.HtmlEmail; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Properties; |
||||
|
||||
import javax.mail.Authenticator; |
||||
import javax.mail.Message; |
||||
import javax.mail.MessagingException; |
||||
import javax.mail.PasswordAuthentication; |
||||
import javax.mail.Session; |
||||
import javax.mail.Transport; |
||||
import javax.mail.internet.InternetAddress; |
||||
import javax.mail.internet.MimeBodyPart; |
||||
import javax.mail.internet.MimeMessage; |
||||
import javax.mail.internet.MimeMultipart; |
||||
import javax.mail.internet.MimeUtility; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import com.sun.mail.smtp.SMTPProvider; |
||||
|
||||
/** |
||||
* mail utils |
||||
*/ |
||||
public class MailSender { |
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(MailSender.class); |
||||
|
||||
private List<String> receivers; |
||||
private List<String> receiverCcs; |
||||
private String mailProtocol = "SMTP"; |
||||
private String mailSmtpHost; |
||||
private String mailSmtpPort; |
||||
private String mailSender; |
||||
private String enableSmtpAuth; |
||||
private String mailUser; |
||||
private String mailPasswd; |
||||
private String mailUseStartTLS; |
||||
private String mailUseSSL; |
||||
private String xlsFilePath; |
||||
private String sslTrust; |
||||
private String showType; |
||||
private AlertTemplate alertTemplate; |
||||
|
||||
public MailSender(Map<String, String> config) { |
||||
|
||||
String receiversConfig = config.get(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS); |
||||
if (receiversConfig == null || "".equals(receiversConfig)) { |
||||
throw new RuntimeException(MailParamsConstants.PLUGIN_DEFAULT_EMAIL_RECEIVERS + "must not be null"); |
||||
} |
||||
|
||||
receivers = Arrays.asList(receiversConfig.split(",")); |
||||
|
||||
String receiverCcsConfig = config.get(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS); |
||||
|
||||
receiverCcs = new ArrayList<>(); |
||||
if (receiverCcsConfig != null && !"".equals(receiverCcsConfig)) { |
||||
receiverCcs = Arrays.asList(receiverCcsConfig.split(",")); |
||||
} |
||||
|
||||
mailSmtpHost = config.get(MailParamsConstants.NAME_MAIL_SMTP_HOST); |
||||
requireNonNull(mailSmtpHost, MailParamsConstants.MAIL_SMTP_HOST + " must not null"); |
||||
|
||||
mailSmtpPort = config.get(MailParamsConstants.NAME_MAIL_SMTP_PORT); |
||||
requireNonNull(mailSmtpPort, MailParamsConstants.MAIL_SMTP_PORT + " must not null"); |
||||
|
||||
mailSender = config.get(MailParamsConstants.NAME_MAIL_SENDER); |
||||
requireNonNull(mailSender, MailParamsConstants.MAIL_SENDER + " must not null"); |
||||
|
||||
enableSmtpAuth = config.get(MailParamsConstants.NAME_MAIL_SMTP_AUTH); |
||||
|
||||
mailUser = config.get(MailParamsConstants.NAME_MAIL_USER); |
||||
requireNonNull(mailUser, MailParamsConstants.MAIL_USER + " must not null"); |
||||
|
||||
mailPasswd = config.get(MailParamsConstants.NAME_MAIL_PASSWD); |
||||
requireNonNull(mailPasswd, MailParamsConstants.MAIL_PASSWD + " must not null"); |
||||
|
||||
mailUseStartTLS = config.get(MailParamsConstants.NAME_MAIL_SMTP_STARTTLS_ENABLE); |
||||
requireNonNull(mailUseStartTLS, MailParamsConstants.MAIL_SMTP_STARTTLS_ENABLE + " must not null"); |
||||
|
||||
mailUseSSL = config.get(MailParamsConstants.NAME_MAIL_SMTP_SSL_ENABLE); |
||||
requireNonNull(mailUseSSL, MailParamsConstants.MAIL_SMTP_SSL_ENABLE + " must not null"); |
||||
|
||||
sslTrust = config.get(MailParamsConstants.NAME_MAIL_SMTP_SSL_TRUST); |
||||
requireNonNull(sslTrust, MailParamsConstants.MAIL_SMTP_SSL_TRUST + " must not null"); |
||||
|
||||
showType = config.get(AlertConstants.SHOW_TYPE); |
||||
requireNonNull(showType, AlertConstants.SHOW_TYPE + " must not null"); |
||||
|
||||
xlsFilePath = config.get(EmailConstants.XLS_FILE_PATH); |
||||
if (StringUtils.isBlank(xlsFilePath)) { |
||||
xlsFilePath = "/tmp/xls"; |
||||
} |
||||
|
||||
alertTemplate = new DefaultHTMLTemplate(); |
||||
} |
||||
|
||||
/** |
||||
* send mail to receivers |
||||
* |
||||
* @param title title |
||||
* @param content content |
||||
* @return |
||||
*/ |
||||
public AlertResult sendMails(String title, String content) { |
||||
return sendMails(this.receivers, this.receiverCcs, title, content); |
||||
} |
||||
|
||||
/** |
||||
* send mail to receivers |
||||
* |
||||
* @param title email title |
||||
* @param content email content |
||||
* @return |
||||
*/ |
||||
public AlertResult sendMailsToReceiverOnly(String title, String content) { |
||||
return sendMails(this.receivers, null, title, content); |
||||
} |
||||
|
||||
/** |
||||
* send mail |
||||
* |
||||
* @param receivers receivers |
||||
* @param receiverCcs receiverCcs |
||||
* @param title title |
||||
* @param content content |
||||
* @return |
||||
*/ |
||||
public AlertResult sendMails(List<String> receivers, List<String> receiverCcs, String title, String content) { |
||||
AlertResult alertResult = new AlertResult(); |
||||
alertResult.setStatus("false"); |
||||
|
||||
// if there is no receivers && no receiversCc, no need to process
|
||||
if (CollectionUtils.isEmpty(receivers) && CollectionUtils.isEmpty(receiverCcs)) { |
||||
return alertResult; |
||||
} |
||||
|
||||
receivers.removeIf(StringUtils::isEmpty); |
||||
|
||||
if (showType.equals(ShowType.TABLE.getDescp()) || showType.equals(ShowType.TEXT.getDescp())) { |
||||
// send email
|
||||
HtmlEmail email = new HtmlEmail(); |
||||
|
||||
try { |
||||
Session session = getSession(); |
||||
email.setMailSession(session); |
||||
email.setFrom(mailSender); |
||||
email.setCharset(EmailConstants.UTF_8); |
||||
if (CollectionUtils.isNotEmpty(receivers)) { |
||||
// receivers mail
|
||||
for (String receiver : receivers) { |
||||
email.addTo(receiver); |
||||
} |
||||
} |
||||
|
||||
if (CollectionUtils.isNotEmpty(receiverCcs)) { |
||||
//cc
|
||||
for (String receiverCc : receiverCcs) { |
||||
email.addCc(receiverCc); |
||||
} |
||||
} |
||||
// sender mail
|
||||
return getStringObjectMap(title, content, alertResult, email); |
||||
} catch (Exception e) { |
||||
handleException(alertResult, e); |
||||
} |
||||
} else if (showType.equals(ShowType.ATTACHMENT.getDescp()) || showType.equals(ShowType.TABLEATTACHMENT.getDescp())) { |
||||
try { |
||||
|
||||
String partContent = (showType.equals(ShowType.ATTACHMENT.getDescp()) ? "Please see the attachment " + title + EmailConstants.EXCEL_SUFFIX_XLS : htmlTable(content, false)); |
||||
|
||||
attachment(title, content, partContent); |
||||
|
||||
alertResult.setStatus("true"); |
||||
return alertResult; |
||||
} catch (Exception e) { |
||||
handleException(alertResult, e); |
||||
return alertResult; |
||||
} |
||||
} |
||||
return alertResult; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* html table content |
||||
* |
||||
* @param content the content |
||||
* @param showAll if show the whole content |
||||
* @return the html table form |
||||
*/ |
||||
private String htmlTable(String content, boolean showAll) { |
||||
return alertTemplate.getMessageFromTemplate(content, ShowType.TABLE, showAll); |
||||
} |
||||
|
||||
/** |
||||
* html table content |
||||
* |
||||
* @param content the content |
||||
* @return the html table form |
||||
*/ |
||||
private String htmlTable(String content) { |
||||
return htmlTable(content, true); |
||||
} |
||||
|
||||
/** |
||||
* html text content |
||||
* |
||||
* @param content the content |
||||
* @return text in html form |
||||
*/ |
||||
private String htmlText(String content) { |
||||
return alertTemplate.getMessageFromTemplate(content, ShowType.TEXT); |
||||
} |
||||
|
||||
/** |
||||
* send mail as Excel attachment |
||||
* |
||||
* @param title |
||||
* @param content |
||||
* @param partContent |
||||
* @throws Exception |
||||
*/ |
||||
private void attachment(String title, String content, String partContent) throws Exception { |
||||
MimeMessage msg = getMimeMessage(); |
||||
|
||||
attachContent(title, content, partContent, msg); |
||||
} |
||||
|
||||
/** |
||||
* get MimeMessage |
||||
* |
||||
* @return |
||||
* @throws MessagingException |
||||
*/ |
||||
private MimeMessage getMimeMessage() throws MessagingException { |
||||
|
||||
// 1. The first step in creating mail: creating session
|
||||
Session session = getSession(); |
||||
// Setting debug mode, can be turned off
|
||||
session.setDebug(false); |
||||
|
||||
// 2. creating mail: Creating a MimeMessage
|
||||
MimeMessage msg = new MimeMessage(session); |
||||
// 3. set sender
|
||||
msg.setFrom(new InternetAddress(mailSender)); |
||||
// 4. set receivers
|
||||
for (String receiver : receivers) { |
||||
msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver)); |
||||
} |
||||
return msg; |
||||
} |
||||
|
||||
/** |
||||
* get session |
||||
* |
||||
* @return the new Session |
||||
*/ |
||||
private Session getSession() { |
||||
Properties props = new Properties(); |
||||
props.setProperty(MailParamsConstants.MAIL_SMTP_HOST, mailSmtpHost); |
||||
props.setProperty(MailParamsConstants.MAIL_SMTP_PORT, mailSmtpPort); |
||||
props.setProperty(MailParamsConstants.MAIL_SMTP_AUTH, enableSmtpAuth); |
||||
props.setProperty(EmailConstants.MAIL_TRANSPORT_PROTOCOL, mailProtocol); |
||||
props.setProperty(MailParamsConstants.MAIL_SMTP_STARTTLS_ENABLE, mailUseStartTLS); |
||||
props.setProperty(MailParamsConstants.MAIL_SMTP_SSL_ENABLE, mailUseSSL); |
||||
props.setProperty(MailParamsConstants.MAIL_SMTP_SSL_TRUST, sslTrust); |
||||
|
||||
Authenticator auth = new Authenticator() { |
||||
@Override |
||||
protected PasswordAuthentication getPasswordAuthentication() { |
||||
// mail username and password
|
||||
return new PasswordAuthentication(mailUser, mailPasswd); |
||||
} |
||||
}; |
||||
|
||||
Session session = Session.getInstance(props, auth); |
||||
session.addProvider(new SMTPProvider()); |
||||
return session; |
||||
} |
||||
|
||||
/** |
||||
* attach content |
||||
* |
||||
* @param title |
||||
* @param content |
||||
* @param partContent |
||||
* @param msg |
||||
* @throws MessagingException |
||||
* @throws IOException |
||||
*/ |
||||
private void attachContent(String title, String content, String partContent, MimeMessage msg) throws MessagingException, IOException { |
||||
/** |
||||
* set receiverCc |
||||
*/ |
||||
if (CollectionUtils.isNotEmpty(receiverCcs)) { |
||||
for (String receiverCc : receiverCcs) { |
||||
msg.addRecipients(Message.RecipientType.CC, InternetAddress.parse(receiverCc)); |
||||
} |
||||
} |
||||
|
||||
// set subject
|
||||
msg.setSubject(title); |
||||
MimeMultipart partList = new MimeMultipart(); |
||||
// set signature
|
||||
MimeBodyPart part1 = new MimeBodyPart(); |
||||
part1.setContent(partContent, EmailConstants.TEXT_HTML_CHARSET_UTF_8); |
||||
// set attach file
|
||||
MimeBodyPart part2 = new MimeBodyPart(); |
||||
File file = new File(xlsFilePath + EmailConstants.SINGLE_SLASH + title + EmailConstants.EXCEL_SUFFIX_XLS); |
||||
if (!file.getParentFile().exists()) { |
||||
file.getParentFile().mkdirs(); |
||||
} |
||||
// make excel file
|
||||
|
||||
ExcelUtils.genExcelFile(content, title, xlsFilePath); |
||||
|
||||
part2.attachFile(file); |
||||
part2.setFileName(MimeUtility.encodeText(title + EmailConstants.EXCEL_SUFFIX_XLS, EmailConstants.UTF_8, "B")); |
||||
// add components to collection
|
||||
partList.addBodyPart(part1); |
||||
partList.addBodyPart(part2); |
||||
msg.setContent(partList); |
||||
// 5. send Transport
|
||||
Transport.send(msg); |
||||
// 6. delete saved file
|
||||
deleteFile(file); |
||||
} |
||||
|
||||
/** |
||||
* the string object map |
||||
* |
||||
* @param title |
||||
* @param content |
||||
* @param alertResult |
||||
* @param email |
||||
* @return |
||||
* @throws EmailException |
||||
*/ |
||||
private AlertResult getStringObjectMap(String title, String content, AlertResult alertResult, HtmlEmail email) throws EmailException { |
||||
|
||||
/** |
||||
* the subject of the message to be sent |
||||
*/ |
||||
email.setSubject(title); |
||||
/** |
||||
* to send information, you can use HTML tags in mail content because of the use of HtmlEmail |
||||
*/ |
||||
if (showType.equals(ShowType.TABLE.getDescp())) { |
||||
email.setMsg(htmlTable(content)); |
||||
} else if (showType.equals(ShowType.TEXT.getDescp())) { |
||||
email.setMsg(htmlText(content)); |
||||
} |
||||
|
||||
// send
|
||||
email.setDebug(true); |
||||
Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); |
||||
email.send(); |
||||
|
||||
alertResult.setStatus("true"); |
||||
|
||||
return alertResult; |
||||
} |
||||
|
||||
/** |
||||
* file delete |
||||
* |
||||
* @param file the file to delete |
||||
*/ |
||||
public void deleteFile(File file) { |
||||
if (file.exists()) { |
||||
if (file.delete()) { |
||||
logger.info("delete success: {}", file.getAbsolutePath() + file.getName()); |
||||
} else { |
||||
logger.info("delete fail: {}", file.getAbsolutePath() + file.getName()); |
||||
} |
||||
} else { |
||||
logger.info("file not exists: {}", file.getAbsolutePath() + file.getName()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* handle exception |
||||
* |
||||
* @param alertResult |
||||
* @param e |
||||
*/ |
||||
private void handleException(AlertResult alertResult, Exception e) { |
||||
logger.error("Send email to {} failed", receivers, e); |
||||
alertResult.setMessage("Send email to {" + String.join(",", receivers) + "} failed," + e.toString()); |
||||
} |
||||
|
||||
} |
@ -1,75 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* EmailAlertChannelFactory Tester. |
||||
* |
||||
* @version 1.0 |
||||
* @since <pre>Aug 20, 2020</pre> |
||||
*/ |
||||
public class EmailAlertChannelFactoryTest { |
||||
|
||||
@Before |
||||
public void before() throws Exception { |
||||
} |
||||
|
||||
@After |
||||
public void after() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Method: getName() |
||||
*/ |
||||
@Test |
||||
public void testGetName() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Method: getParams() |
||||
*/ |
||||
@Test |
||||
public void testGetParams() throws Exception { |
||||
EmailAlertChannelFactory emailAlertChannelFactory = new EmailAlertChannelFactory(); |
||||
List<PluginParams> params = emailAlertChannelFactory.getParams(); |
||||
System.out.println(JSONUtils.toJsonString(params)); |
||||
Assert.assertEquals(12, params.size()); |
||||
} |
||||
|
||||
/** |
||||
* Method: create() |
||||
*/ |
||||
@Test |
||||
public void testCreate() throws Exception { |
||||
EmailAlertChannelFactory emailAlertChannelFactory = new EmailAlertChannelFactory(); |
||||
AlertChannel alertChannel = emailAlertChannelFactory.create(); |
||||
Assert.assertNotNull(alertChannel); |
||||
} |
||||
|
||||
} |
@ -1,161 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertConstants; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertData; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertInfo; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.alert.ShowType; |
||||
import org.apache.dolphinscheduler.spi.params.InputParam; |
||||
import org.apache.dolphinscheduler.spi.params.PasswordParam; |
||||
import org.apache.dolphinscheduler.spi.params.RadioParam; |
||||
import org.apache.dolphinscheduler.spi.params.base.DataType; |
||||
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.params.base.Validate; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* EmailAlertChannel Tester. |
||||
*/ |
||||
public class EmailAlertChannelTest { |
||||
|
||||
/** |
||||
* Method: process(AlertInfo info) |
||||
*/ |
||||
@Test |
||||
public void testProcess() { |
||||
EmailAlertChannel emailAlertChannel = new EmailAlertChannel(); |
||||
AlertData alertData = new AlertData(); |
||||
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>(); |
||||
map1.put("mysql service name", "mysql200"); |
||||
map1.put("mysql address", "192.168.xx.xx"); |
||||
map1.put("port", "3306"); |
||||
map1.put("no index of number", "80"); |
||||
map1.put("database client connections", "190"); |
||||
List<LinkedHashMap<String, Object>> maps = new ArrayList<>(); |
||||
maps.add(0, map1); |
||||
String mapjson = JSONUtils.toJsonString(maps); |
||||
|
||||
alertData.setId(10) |
||||
.setContent(mapjson) |
||||
.setLog("10") |
||||
.setTitle("test"); |
||||
AlertInfo alertInfo = new AlertInfo(); |
||||
alertInfo.setAlertData(alertData); |
||||
alertInfo.setAlertParams(getEmailAlertParams()); |
||||
AlertResult alertResult = emailAlertChannel.process(alertInfo); |
||||
Assert.assertNotNull(alertResult); |
||||
Assert.assertEquals("false", alertResult.getStatus()); |
||||
} |
||||
|
||||
public String getEmailAlertParams() { |
||||
List<PluginParams> paramsList = new ArrayList<>(); |
||||
InputParam receivesParam = InputParam.newBuilder("receivers", "receivers") |
||||
.setValue("540957506@qq.com") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
InputParam mailSmtpHost = InputParam.newBuilder("serverHost", "smtp.host") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.setValue("smtp.126.com") |
||||
.build(); |
||||
|
||||
InputParam mailSmtpPort = InputParam.newBuilder("serverPort", "smtp.port") |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.setType(DataType.NUMBER.getDataType()) |
||||
.build()) |
||||
.setValue(25) |
||||
.build(); |
||||
|
||||
InputParam mailSender = InputParam.newBuilder("sender", "sender") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.setValue("dolphinscheduler@126.com") |
||||
.build(); |
||||
|
||||
RadioParam enableSmtpAuth = RadioParam.newBuilder("enableSmtpAuth", "smtp.auth") |
||||
.addParamsOptions(new ParamsOptions("YES", true, false)) |
||||
.addParamsOptions(new ParamsOptions("NO", false, false)) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.setValue(false) |
||||
.build(); |
||||
|
||||
InputParam mailUser = InputParam.newBuilder("user", "user") |
||||
.setPlaceholder("if enable use authentication, you need input user") |
||||
.setValue("dolphinscheduler@126.com") |
||||
.build(); |
||||
|
||||
PasswordParam mailPassword = PasswordParam.newBuilder("passwd", "passwd") |
||||
.setPlaceholder("if enable use authentication, you need input password") |
||||
.setValue("escheduler123") |
||||
.build(); |
||||
|
||||
RadioParam enableTls = RadioParam.newBuilder("starttlsEnable", "starttls.enable") |
||||
.addParamsOptions(new ParamsOptions("YES", true, false)) |
||||
.addParamsOptions(new ParamsOptions("NO", false, false)) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.setValue(true) |
||||
.build(); |
||||
|
||||
RadioParam enableSsl = RadioParam.newBuilder("sslEnable", "smtp.ssl.enable") |
||||
.addParamsOptions(new ParamsOptions("YES", true, false)) |
||||
.addParamsOptions(new ParamsOptions("NO", false, false)) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.setValue(true) |
||||
.build(); |
||||
|
||||
InputParam sslTrust = InputParam.newBuilder("smtpSslTrust", "smtp.ssl.trust") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.setValue("smtp.126.com") |
||||
.build(); |
||||
|
||||
List<ParamsOptions> emailShowTypeList = new ArrayList<>(); |
||||
emailShowTypeList.add(new ParamsOptions(ShowType.TABLE.getDescp(), ShowType.TABLE.getDescp(), false)); |
||||
emailShowTypeList.add(new ParamsOptions(ShowType.TEXT.getDescp(), ShowType.TEXT.getDescp(), false)); |
||||
emailShowTypeList.add(new ParamsOptions(ShowType.ATTACHMENT.getDescp(), ShowType.ATTACHMENT.getDescp(), false)); |
||||
emailShowTypeList.add(new ParamsOptions(ShowType.TABLEATTACHMENT.getDescp(), ShowType.TABLEATTACHMENT.getDescp(), false)); |
||||
RadioParam showType = RadioParam.newBuilder(AlertConstants.SHOW_TYPE, "showType") |
||||
.setParamsOptionsList(emailShowTypeList) |
||||
.setValue(ShowType.TABLE.getDescp()) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
paramsList.add(receivesParam); |
||||
paramsList.add(mailSmtpHost); |
||||
paramsList.add(mailSmtpPort); |
||||
paramsList.add(mailSender); |
||||
paramsList.add(enableSmtpAuth); |
||||
paramsList.add(mailUser); |
||||
paramsList.add(mailPassword); |
||||
paramsList.add(enableTls); |
||||
paramsList.add(enableSsl); |
||||
paramsList.add(sslTrust); |
||||
paramsList.add(showType); |
||||
|
||||
return JSONUtils.toJsonString(paramsList); |
||||
} |
||||
} |
@ -1,136 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.alert.email.template.AlertTemplate; |
||||
import org.apache.dolphinscheduler.plugin.alert.email.template.DefaultHTMLTemplate; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertConstants; |
||||
import org.apache.dolphinscheduler.spi.alert.ShowType; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.BeforeClass; |
||||
import org.junit.Test; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
*/ |
||||
public class MailUtilsTest { |
||||
private static final Logger logger = LoggerFactory.getLogger(MailUtilsTest.class); |
||||
|
||||
private static Map<String, String> emailConfig = new HashMap<>(); |
||||
|
||||
private static AlertTemplate alertTemplate; |
||||
|
||||
static MailSender mailSender; |
||||
|
||||
@BeforeClass |
||||
public static void initEmailConfig() { |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_PROTOCOL, "smtp"); |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_HOST, "xxx.xxx.com"); |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_PORT, "25"); |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_SENDER, "xxx1.xxx.com"); |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_USER, "xxx2.xxx.com"); |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_PASSWD, "111111"); |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_STARTTLS_ENABLE, "true"); |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_SSL_ENABLE, "false"); |
||||
emailConfig.put(MailParamsConstants.NAME_MAIL_SMTP_SSL_TRUST, "false"); |
||||
emailConfig.put(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS, "347801120@qq.com"); |
||||
emailConfig.put(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS, "347801120@qq.com"); |
||||
emailConfig.put(AlertConstants.SHOW_TYPE, ShowType.TEXT.getDescp()); |
||||
alertTemplate = new DefaultHTMLTemplate(); |
||||
mailSender = new MailSender(emailConfig); |
||||
} |
||||
|
||||
@Test |
||||
public void testSendMails() { |
||||
|
||||
String content = "[\"id:69\"," |
||||
+ "\"name:UserBehavior-0--1193959466\"," |
||||
+ "\"Job name: Start workflow\"," |
||||
+ "\"State: SUCCESS\"," |
||||
+ "\"Recovery:NO\"," |
||||
+ "\"Run time: 1\"," |
||||
+ "\"Start time: 2018-08-06 10:31:34.0\"," |
||||
+ "\"End time: 2018-08-06 10:31:49.0\"," |
||||
+ "\"Host: 192.168.xx.xx\"," |
||||
+ "\"Notify group :4\"]"; |
||||
|
||||
mailSender.sendMails( |
||||
"Mysql Exception", |
||||
content); |
||||
} |
||||
|
||||
public String list2String() { |
||||
|
||||
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>(); |
||||
map1.put("mysql service name", "mysql200"); |
||||
map1.put("mysql address", "192.168.xx.xx"); |
||||
map1.put("port", "3306"); |
||||
map1.put("no index of number", "80"); |
||||
map1.put("database client connections", "190"); |
||||
|
||||
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>(); |
||||
map2.put("mysql service name", "mysql210"); |
||||
map2.put("mysql address", "192.168.xx.xx"); |
||||
map2.put("port", "3306"); |
||||
map2.put("no index of number", "10"); |
||||
map2.put("database client connections", "90"); |
||||
|
||||
List<LinkedHashMap<String, Object>> maps = new ArrayList<>(); |
||||
maps.add(0, map1); |
||||
maps.add(1, map2); |
||||
String mapjson = JSONUtils.toJsonString(maps); |
||||
logger.info(mapjson); |
||||
|
||||
return mapjson; |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testSendTableMail() { |
||||
String title = "Mysql Exception"; |
||||
String content = list2String(); |
||||
emailConfig.put(AlertConstants.SHOW_TYPE, ShowType.TABLE.getDescp()); |
||||
mailSender = new MailSender(emailConfig); |
||||
mailSender.sendMails(title, content); |
||||
} |
||||
|
||||
@Test |
||||
public void testAttachmentFile() throws Exception { |
||||
String content = list2String(); |
||||
emailConfig.put(AlertConstants.SHOW_TYPE, ShowType.ATTACHMENT.getDescp()); |
||||
mailSender = new MailSender(emailConfig); |
||||
mailSender.sendMails("gaojing", content); |
||||
} |
||||
|
||||
@Test |
||||
public void testTableAttachmentFile() throws Exception { |
||||
String content = list2String(); |
||||
emailConfig.put(AlertConstants.SHOW_TYPE, ShowType.TABLEATTACHMENT.getDescp()); |
||||
mailSender = new MailSender(emailConfig); |
||||
mailSender.sendMails("gaojing", content); |
||||
} |
||||
|
||||
} |
@ -1,105 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.email.template; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.alert.email.EmailConstants; |
||||
import org.apache.dolphinscheduler.spi.alert.ShowType; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
|
||||
import org.junit.Test; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* test class for DefaultHTMLTemplate |
||||
*/ |
||||
public class DefaultHTMLTemplateTest { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultHTMLTemplateTest.class); |
||||
|
||||
/** |
||||
* only need test method GetMessageFromTemplate |
||||
*/ |
||||
@Test |
||||
public void testGetMessageFromTemplate() { |
||||
|
||||
DefaultHTMLTemplate template = new DefaultHTMLTemplate(); |
||||
|
||||
String tableTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TABLE, true); |
||||
|
||||
assertEquals(tableTypeMessage, generateMockTableTypeResultByHand()); |
||||
|
||||
String textTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TEXT, true); |
||||
|
||||
assertEquals(textTypeMessage, generateMockTextTypeResultByHand()); |
||||
} |
||||
|
||||
/** |
||||
* generate some simulation data |
||||
*/ |
||||
private String list2String() { |
||||
|
||||
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>(); |
||||
map1.put("mysql service name", "mysql200"); |
||||
map1.put("mysql address", "192.168.xx.xx"); |
||||
map1.put("database client connections", "190"); |
||||
map1.put("port", "3306"); |
||||
map1.put("no index of number", "80"); |
||||
|
||||
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>(); |
||||
map2.put("mysql service name", "mysql210"); |
||||
map2.put("mysql address", "192.168.xx.xx"); |
||||
map2.put("database client connections", "90"); |
||||
map2.put("port", "3306"); |
||||
map2.put("no index of number", "10"); |
||||
|
||||
List<LinkedHashMap<String, Object>> maps = new ArrayList<>(); |
||||
maps.add(0, map1); |
||||
maps.add(1, map2); |
||||
String mapjson = JSONUtils.toJsonString(maps); |
||||
logger.info(mapjson); |
||||
|
||||
return mapjson; |
||||
} |
||||
|
||||
private String generateMockTableTypeResultByHand() { |
||||
|
||||
return EmailConstants.HTML_HEADER_PREFIX |
||||
+ "<thead>" |
||||
+ "<tr><th>mysql service name</th><th>mysql address</th><th>database client connections</th><th>port</th><th>no index of number</th></tr>" |
||||
+ "</thead>\n" |
||||
+ "<tr><td>mysql200</td><td>192.168.xx.xx</td><td>190</td><td>3306</td><td>80</td></tr>" |
||||
+ "<tr><td>mysql210</td><td>192.168.xx.xx</td><td>90</td><td>3306</td><td>10</td></tr>" |
||||
+ EmailConstants.TABLE_BODY_HTML_TAIL; |
||||
|
||||
} |
||||
|
||||
private String generateMockTextTypeResultByHand() { |
||||
|
||||
return EmailConstants.HTML_HEADER_PREFIX |
||||
+ "<tr><td>{\"mysql service name\":\"mysql200\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"190\",\"port\":\"3306\",\"no index of number\":\"80\"}</td></tr>" |
||||
+ "<tr><td>{\"mysql service name\":\"mysql210\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"90\",\"port\":\"3306\",\"no index of number\":\"10\"}</td></tr>" |
||||
+ EmailConstants.TABLE_BODY_HTML_TAIL; |
||||
} |
||||
} |
@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
<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"> |
||||
<parent> |
||||
<artifactId>dolphinscheduler-alert-plugin</artifactId> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<version>1.3.4-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>dolphinscheduler-alert-http</artifactId> |
||||
<packaging>dolphinscheduler-plugin</packaging> |
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-spi</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>ch.qos.logback</groupId> |
||||
<artifactId>logback-classic</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.httpcomponents</groupId> |
||||
<artifactId>httpclient</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-databind</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>junit</groupId> |
||||
<artifactId>junit</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.mockito</groupId> |
||||
<artifactId>mockito-core</artifactId> |
||||
<type>jar</type> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
<build> |
||||
<finalName>dolphinscheduler-alert-http-${project.version}</finalName> |
||||
</build> |
||||
|
||||
</project> |
@ -1,41 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.http; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertData; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertInfo; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* http alert channel,use sms message to seed the alertInfo |
||||
*/ |
||||
public class HttpAlertChannel implements AlertChannel { |
||||
@Override |
||||
public AlertResult process(AlertInfo alertInfo) { |
||||
|
||||
AlertData alertData = alertInfo.getAlertData(); |
||||
String alertParams = alertInfo.getAlertParams(); |
||||
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams); |
||||
|
||||
return new HttpSender(paramsMap).send(alertData.getContent()); |
||||
} |
||||
} |
@ -1,78 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.http; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
import org.apache.dolphinscheduler.spi.params.InputParam; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.params.base.Validate; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* http alert factory |
||||
*/ |
||||
public class HttpAlertChannelFactory implements AlertChannelFactory { |
||||
@Override |
||||
public String getName() { |
||||
return "Http"; |
||||
} |
||||
|
||||
@Override |
||||
public List<PluginParams> getParams() { |
||||
|
||||
InputParam url = InputParam.newBuilder(HttpAlertConstants.URL, HttpAlertConstants.URL) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam headerParams = InputParam.newBuilder(HttpAlertConstants.HEADER_PARAMS, HttpAlertConstants.HEADER_PARAMS) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam bodyParams = InputParam.newBuilder(HttpAlertConstants.BODY_PARAMS, HttpAlertConstants.BODY_PARAMS) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam contentField = InputParam.newBuilder(HttpAlertConstants.CONTENT_FIELD, HttpAlertConstants.CONTENT_FIELD) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam requestType = InputParam.newBuilder(HttpAlertConstants.REQUEST_TYPE, HttpAlertConstants.REQUEST_TYPE) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
return Arrays.asList(url, requestType, headerParams, bodyParams, contentField); |
||||
} |
||||
|
||||
@Override |
||||
public AlertChannel create() { |
||||
return new HttpAlertChannel(); |
||||
} |
||||
} |
@ -1,35 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.http; |
||||
|
||||
public class HttpAlertConstants { |
||||
|
||||
private HttpAlertConstants() { |
||||
} |
||||
|
||||
public static final String URL = "url"; |
||||
|
||||
public static final String HEADER_PARAMS = "headerParams"; |
||||
|
||||
public static final String BODY_PARAMS = "bodyParams"; |
||||
|
||||
public static final String CONTENT_FIELD = "contentField"; |
||||
|
||||
public static final String REQUEST_TYPE = "requestType"; |
||||
|
||||
} |
@ -1,34 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.http; |
||||
|
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
|
||||
/** |
||||
* http alertPlugins |
||||
*/ |
||||
public class HttpAlertPlugin implements DolphinSchedulerPlugin { |
||||
|
||||
@Override |
||||
public Iterable<AlertChannelFactory> getAlertChannelFactorys() { |
||||
return ImmutableList.of(new HttpAlertChannelFactory()); |
||||
} |
||||
} |
@ -1,166 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.http; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||
|
||||
import org.apache.http.HttpEntity; |
||||
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
import org.apache.http.client.methods.HttpGet; |
||||
import org.apache.http.client.methods.HttpPost; |
||||
import org.apache.http.client.methods.HttpRequestBase; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.apache.http.impl.client.HttpClientBuilder; |
||||
import org.apache.http.util.EntityUtils; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode; |
||||
|
||||
/** |
||||
* http send message |
||||
*/ |
||||
public class HttpSender { |
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(HttpSender.class); |
||||
|
||||
private String url; |
||||
|
||||
private final String headerParams; |
||||
|
||||
private final String bodyParams; |
||||
|
||||
private final String contentField; |
||||
|
||||
private final String requestType; |
||||
|
||||
private HttpRequestBase httpRequest; |
||||
|
||||
|
||||
private static final String URL_SPLICE_CHAR = "?"; |
||||
|
||||
/** |
||||
* request type post |
||||
*/ |
||||
private static final String REQUEST_TYPE_POST = "POST"; |
||||
|
||||
/** |
||||
* request type get |
||||
*/ |
||||
private static final String REQUEST_TYPE_GET = "GET"; |
||||
|
||||
private static final String DEFAULT_CHARSET = "utf-8"; |
||||
|
||||
public HttpSender(Map<String, String> paramsMap) { |
||||
|
||||
url = paramsMap.get(HttpAlertConstants.URL); |
||||
headerParams = paramsMap.get(HttpAlertConstants.HEADER_PARAMS); |
||||
bodyParams = paramsMap.get(HttpAlertConstants.BODY_PARAMS); |
||||
contentField = paramsMap.get(HttpAlertConstants.CONTENT_FIELD); |
||||
requestType = paramsMap.get(HttpAlertConstants.REQUEST_TYPE); |
||||
} |
||||
|
||||
public AlertResult send(String msg) { |
||||
|
||||
AlertResult alertResult = new AlertResult(); |
||||
|
||||
createHttpRequest(msg); |
||||
|
||||
if (httpRequest == null) { |
||||
alertResult.setStatus("false"); |
||||
alertResult.setMessage("Request types are not supported"); |
||||
return alertResult; |
||||
} |
||||
|
||||
try { |
||||
CloseableHttpClient httpClient = HttpClientBuilder.create().build(); |
||||
CloseableHttpResponse response = httpClient.execute(httpRequest); |
||||
HttpEntity entity = response.getEntity(); |
||||
String resp = EntityUtils.toString(entity, DEFAULT_CHARSET); |
||||
alertResult.setStatus("true"); |
||||
alertResult.setMessage(resp); |
||||
} catch (Exception e) { |
||||
logger.error("send http alert msg exception : {}", e.getMessage()); |
||||
alertResult.setStatus("false"); |
||||
alertResult.setMessage("send http request alert fail."); |
||||
} |
||||
|
||||
return alertResult; |
||||
} |
||||
|
||||
private void createHttpRequest(String msg) { |
||||
|
||||
if (REQUEST_TYPE_POST.equals(requestType)) { |
||||
httpRequest = new HttpPost(url); |
||||
//POST request add param in request body
|
||||
setMsgInRequestBody(msg); |
||||
} else if (REQUEST_TYPE_GET.equals(requestType)) { |
||||
//GET request add param in url
|
||||
setMsgInUrl(msg); |
||||
httpRequest = new HttpGet(url); |
||||
} |
||||
setHeader(); |
||||
} |
||||
|
||||
/** |
||||
* add msg param in url |
||||
*/ |
||||
private void setMsgInUrl(String msg) { |
||||
|
||||
if (StringUtils.isNotBlank(contentField)) { |
||||
String type = "&"; |
||||
//check splice char is & or ?
|
||||
if (!url.contains(URL_SPLICE_CHAR)) { |
||||
type = URL_SPLICE_CHAR; |
||||
} |
||||
url = String.format("%s%s%s=%s", url, type, contentField, msg); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* set header params |
||||
*/ |
||||
private void setHeader() { |
||||
|
||||
if (httpRequest == null) { |
||||
return; |
||||
} |
||||
|
||||
HashMap<String, Object> map = JSONUtils.parseObject(headerParams, HashMap.class); |
||||
for (Map.Entry<String, Object> entry : map.entrySet()) { |
||||
httpRequest.setHeader(entry.getKey(), String.valueOf(entry.getValue())); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* set body params |
||||
*/ |
||||
private String setMsgInRequestBody(String msg) { |
||||
ObjectNode objectNode = JSONUtils.parseObject(bodyParams); |
||||
//set msg content field
|
||||
objectNode.put(contentField, msg); |
||||
return objectNode.toString(); |
||||
} |
||||
|
||||
} |
@ -1,104 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.http; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertData; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertInfo; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.params.InputParam; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.params.base.Validate; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* HttpAlertChannel UT |
||||
*/ |
||||
public class HttpAlertChannelTest { |
||||
|
||||
@Test |
||||
public void processTest() { |
||||
|
||||
HttpAlertChannel alertChannel = new HttpAlertChannel(); |
||||
AlertInfo alertInfo = new AlertInfo(); |
||||
AlertData alertData = new AlertData(); |
||||
alertData.setContent("Fault tolerance warning"); |
||||
alertInfo.setAlertData(alertData); |
||||
AlertResult alertResult = alertChannel.process(alertInfo); |
||||
Assert.assertEquals("Request types are not supported", alertResult.getMessage()); |
||||
} |
||||
|
||||
@Test |
||||
public void processTest2() { |
||||
|
||||
HttpAlertChannel alertChannel = new HttpAlertChannel(); |
||||
AlertInfo alertInfo = new AlertInfo(); |
||||
AlertData alertData = new AlertData(); |
||||
alertData.setContent("Fault tolerance warning"); |
||||
alertInfo.setAlertData(alertData); |
||||
alertInfo.setAlertParams(getParams()); |
||||
AlertResult alertResult = alertChannel.process(alertInfo); |
||||
Assert.assertEquals("true", alertResult.getStatus()); |
||||
} |
||||
|
||||
/** |
||||
* create params |
||||
*/ |
||||
private String getParams() { |
||||
|
||||
List<PluginParams> paramsList = new ArrayList<>(); |
||||
InputParam urlParam = InputParam.newBuilder("url", "url") |
||||
.setValue("http://www.baidu.com") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
InputParam headerParams = InputParam.newBuilder("headerParams", "headerParams") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.setValue("{\"Content-Type\":\"application/json\"}") |
||||
.build(); |
||||
|
||||
InputParam bodyParams = InputParam.newBuilder("bodyParams", "bodyParams") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.setValue("{\"number\":\"13457654323\"}") |
||||
.build(); |
||||
|
||||
InputParam content = InputParam.newBuilder("contentField", "contentField") |
||||
.setValue("content") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
InputParam requestType = InputParam.newBuilder("requestType", "requestType") |
||||
.setValue("POST") |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
paramsList.add(urlParam); |
||||
paramsList.add(headerParams); |
||||
paramsList.add(bodyParams); |
||||
paramsList.add(content); |
||||
paramsList.add(requestType); |
||||
|
||||
return JSONUtils.toJsonString(paramsList); |
||||
} |
||||
|
||||
} |
@ -1,38 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.http; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* HttpAlertPlugin UT |
||||
*/ |
||||
public class HttpAlertPluginTest { |
||||
|
||||
@Test |
||||
public void getAlertChannelFactorysTest() { |
||||
|
||||
HttpAlertPlugin httpAlertPlugin = new HttpAlertPlugin(); |
||||
Iterable<AlertChannelFactory> alertChannelFactorys = httpAlertPlugin.getAlertChannelFactorys(); |
||||
Assert.assertNotNull(alertChannelFactorys); |
||||
|
||||
} |
||||
} |
@ -1,46 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.http; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* HttpSender UT |
||||
*/ |
||||
public class HttpSenderTest { |
||||
|
||||
@Test |
||||
public void sendTest() { |
||||
|
||||
Map<String, String> paramsMap = new HashMap<>(); |
||||
paramsMap.put(HttpAlertConstants.URL, "http://www.baidu.com"); |
||||
paramsMap.put(HttpAlertConstants.REQUEST_TYPE, "POST"); |
||||
paramsMap.put(HttpAlertConstants.HEADER_PARAMS, "{\"Content-Type\":\"application/json\"}"); |
||||
paramsMap.put(HttpAlertConstants.BODY_PARAMS, "{\"number\":\"13457654323\"}"); |
||||
paramsMap.put(HttpAlertConstants.CONTENT_FIELD, "content"); |
||||
HttpSender httpSender = new HttpSender(paramsMap); |
||||
AlertResult alertResult = httpSender.send("Fault tolerance warning"); |
||||
Assert.assertEquals("true", alertResult.getStatus()); |
||||
} |
||||
} |
@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
<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"> |
||||
<parent> |
||||
<artifactId>dolphinscheduler-alert-plugin</artifactId> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<version>1.3.4-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-alert-script</artifactId> |
||||
<packaging>dolphinscheduler-plugin</packaging> |
||||
|
||||
<dependencies> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-spi</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>ch.qos.logback</groupId> |
||||
<artifactId>logback-classic</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.slf4j</groupId> |
||||
<artifactId>slf4j-api</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-annotations</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>junit</groupId> |
||||
<artifactId>junit</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.mockito</groupId> |
||||
<artifactId>mockito-core</artifactId> |
||||
<type>jar</type> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
<build> |
||||
<finalName>dolphinscheduler-alert-script-${project.version}</finalName> |
||||
</build> |
||||
|
||||
</project> |
@ -1,32 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
/** |
||||
* OSUtils |
||||
*/ |
||||
public class OSUtils { |
||||
|
||||
public OSUtils() { |
||||
throw new UnsupportedOperationException("Construct OSUtils"); |
||||
} |
||||
|
||||
static Boolean isWindows() { |
||||
return System.getProperty("os.name").startsWith("Windows"); |
||||
} |
||||
} |
@ -1,62 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* ProcessUtils |
||||
*/ |
||||
public class ProcessUtils { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class); |
||||
|
||||
private ProcessUtils() { |
||||
throw new IllegalStateException("Utility class"); |
||||
} |
||||
|
||||
/** |
||||
* executeScript |
||||
* |
||||
* @param cmd cmd params |
||||
* @return exit code |
||||
*/ |
||||
static Integer executeScript(String... cmd) { |
||||
|
||||
int exitCode = -1; |
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(cmd); |
||||
try { |
||||
Process process = processBuilder.start(); |
||||
StreamGobbler inputStreamGobbler = new StreamGobbler(process.getInputStream()); |
||||
StreamGobbler errorStreamGobbler = new StreamGobbler(process.getErrorStream()); |
||||
|
||||
inputStreamGobbler.start(); |
||||
errorStreamGobbler.start(); |
||||
return process.waitFor(); |
||||
} catch (IOException | InterruptedException e) { |
||||
logger.error("execute alert script error {}", e.getMessage()); |
||||
Thread.currentThread().interrupt(); |
||||
} |
||||
|
||||
return exitCode; |
||||
} |
||||
} |
@ -1,40 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertData; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertInfo; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* ScriptAlertChannel |
||||
*/ |
||||
public class ScriptAlertChannel implements AlertChannel { |
||||
|
||||
@Override |
||||
public AlertResult process(AlertInfo alertinfo) { |
||||
AlertData alertData = alertinfo.getAlertData(); |
||||
String alertParams = alertinfo.getAlertParams(); |
||||
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams); |
||||
return new ScriptSender(paramsMap).sendScriptAlert(alertData.getTitle()); |
||||
} |
||||
} |
@ -1,71 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
import org.apache.dolphinscheduler.spi.params.InputParam; |
||||
import org.apache.dolphinscheduler.spi.params.RadioParam; |
||||
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.params.base.Validate; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* ScriptAlertChannelFactory |
||||
*/ |
||||
public class ScriptAlertChannelFactory implements AlertChannelFactory { |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return "Script"; |
||||
} |
||||
|
||||
@Override |
||||
public List<PluginParams> getParams() { |
||||
|
||||
InputParam scriptUserParam = InputParam.newBuilder(ScriptParamsConstants.NAME_SCRIPT_USER_PARAMS, ScriptParamsConstants.SCRIPT_USER_PARAMS) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(false) |
||||
.build()) |
||||
.setPlaceholder("please enter your custom parameters, which will be passed to you when calling your script") |
||||
.build(); |
||||
// need check file type and file exist
|
||||
InputParam scriptPathParam = InputParam.newBuilder(ScriptParamsConstants.NAME_SCRIPT_PATH, ScriptParamsConstants.SCRIPT_PATH) |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.setPlaceholder("please upload the file to the disk directory of the alert server, and ensure that the path is absolute and has the corresponding access rights") |
||||
.build(); |
||||
|
||||
RadioParam scriptTypeParams = RadioParam.newBuilder(ScriptParamsConstants.NAME_SCRIPT_TYPE, ScriptParamsConstants.SCRIPT_TYPE) |
||||
.addParamsOptions(new ParamsOptions(ScriptType.SHELL.getDescp(), ScriptType.SHELL.getCode(), false)) |
||||
.setValue(ScriptType.SHELL.getCode()) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
return Arrays.asList(scriptUserParam, scriptPathParam, scriptTypeParams); |
||||
} |
||||
|
||||
@Override |
||||
public AlertChannel create() { |
||||
return new ScriptAlertChannel(); |
||||
} |
||||
} |
@ -1,35 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
|
||||
/** |
||||
* ScriptAlertPlugin |
||||
*/ |
||||
public class ScriptAlertPlugin implements DolphinSchedulerPlugin { |
||||
|
||||
@Override |
||||
public Iterable<AlertChannelFactory> getAlertChannelFactorys() { |
||||
return ImmutableList.of(new ScriptAlertChannelFactory()); |
||||
} |
||||
|
||||
} |
@ -1,40 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
/** |
||||
* ScriptParamsConstants |
||||
*/ |
||||
public class ScriptParamsConstants { |
||||
|
||||
public ScriptParamsConstants() { |
||||
throw new IllegalStateException("Utility class"); |
||||
} |
||||
|
||||
static final String SCRIPT_TYPE = "type"; |
||||
|
||||
static final String NAME_SCRIPT_TYPE = "type"; |
||||
|
||||
static final String SCRIPT_PATH = "path"; |
||||
|
||||
static final String NAME_SCRIPT_PATH = "path"; |
||||
|
||||
static final String SCRIPT_USER_PARAMS = "user.params"; |
||||
|
||||
static final String NAME_SCRIPT_USER_PARAMS = "userParams"; |
||||
} |
@ -1,74 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* ScriptSender |
||||
*/ |
||||
public class ScriptSender { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ScriptSender.class); |
||||
|
||||
private String scriptPath; |
||||
|
||||
private Integer scriptType; |
||||
|
||||
private String userParams; |
||||
|
||||
ScriptSender(Map<String, String> config) { |
||||
scriptPath = config.get(ScriptParamsConstants.NAME_SCRIPT_PATH); |
||||
scriptType = Integer.parseInt(config.get(ScriptParamsConstants.NAME_SCRIPT_TYPE)); |
||||
userParams = config.get(ScriptParamsConstants.NAME_SCRIPT_USER_PARAMS); |
||||
} |
||||
|
||||
AlertResult sendScriptAlert(String msg) { |
||||
AlertResult alertResult = new AlertResult(); |
||||
if (ScriptType.of(scriptType).equals(ScriptType.SHELL)) { |
||||
return executeShellScript(msg); |
||||
} |
||||
return alertResult; |
||||
} |
||||
|
||||
private AlertResult executeShellScript(String msg) { |
||||
AlertResult alertResult = new AlertResult(); |
||||
alertResult.setStatus("false"); |
||||
if (Boolean.TRUE.equals(OSUtils.isWindows())) { |
||||
alertResult.setMessage("shell script not support windows os"); |
||||
return alertResult; |
||||
} |
||||
String[] cmd = {"/bin/sh", "-c", scriptPath + " " + msg + " " + userParams}; |
||||
int exitCode = ProcessUtils.executeScript(cmd); |
||||
|
||||
if (exitCode == 0) { |
||||
alertResult.setStatus("true"); |
||||
alertResult.setMessage("send script alert msg success"); |
||||
return alertResult; |
||||
} |
||||
alertResult.setMessage("send script alert msg error,exitCode is " + exitCode); |
||||
logger.info("send script alert msg error,exitCode is {}", exitCode); |
||||
return alertResult; |
||||
} |
||||
|
||||
} |
@ -1,37 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* ProcessUtilsTest |
||||
*/ |
||||
public class ProcessUtilsTest { |
||||
|
||||
private static final String rootPath = System.getProperty("user.dir"); |
||||
|
||||
private static final String shellFilPath = rootPath + "/dolphinscheduler-alert-plugin/dolphinscheduler-alert-script/src/test/script/shell/example.sh"; |
||||
|
||||
private String[] cmd = {"/bin/sh", "-c", shellFilPath + " " + "testMsg" + " " + "userParams"}; |
||||
|
||||
@Test |
||||
public void testExecuteScript() { |
||||
ProcessUtils.executeScript(cmd); |
||||
} |
||||
} |
@ -1,48 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* ScriptAlertChannelFactoryTest |
||||
*/ |
||||
public class ScriptAlertChannelFactoryTest { |
||||
|
||||
@Test |
||||
public void testGetParams() { |
||||
ScriptAlertChannelFactory scriptAlertChannelFactory = new ScriptAlertChannelFactory(); |
||||
List<PluginParams> params = scriptAlertChannelFactory.getParams(); |
||||
JSONUtils.toJsonString(params); |
||||
Assert.assertEquals(3, params.size()); |
||||
} |
||||
|
||||
@Test |
||||
public void testCreate() { |
||||
ScriptAlertChannelFactory scriptAlertChannelFactory = new ScriptAlertChannelFactory(); |
||||
AlertChannel alertChannel = scriptAlertChannelFactory.create(); |
||||
Assert.assertNotNull(alertChannel); |
||||
} |
||||
} |
@ -1,58 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.script; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* ScriptSenderTest |
||||
*/ |
||||
public class ScriptSenderTest { |
||||
|
||||
private static Map<String, String> scriptConfig = new HashMap<>(); |
||||
|
||||
private static final String rootPath = System.getProperty("user.dir"); |
||||
|
||||
private static final String shellFilPath = rootPath + "/src/test/script/shell/scriptTest.sh"; |
||||
|
||||
@Before |
||||
public void initScriptConfig() { |
||||
|
||||
scriptConfig.put(ScriptParamsConstants.NAME_SCRIPT_TYPE, String.valueOf(ScriptType.SHELL.getCode())); |
||||
scriptConfig.put(ScriptParamsConstants.NAME_SCRIPT_USER_PARAMS, "userParams"); |
||||
scriptConfig.put(ScriptParamsConstants.NAME_SCRIPT_PATH, shellFilPath); |
||||
} |
||||
|
||||
@Test |
||||
public void testScriptSenderTest() { |
||||
ScriptSender scriptSender = new ScriptSender(scriptConfig); |
||||
AlertResult alertResult; |
||||
alertResult = scriptSender.sendScriptAlert("success"); |
||||
Assert.assertEquals("true", alertResult.getStatus()); |
||||
alertResult = scriptSender.sendScriptAlert("errorMsg"); |
||||
Assert.assertEquals("false", alertResult.getStatus()); |
||||
} |
||||
|
||||
} |
@ -1,25 +0,0 @@
|
||||
# |
||||
# Licensed to the Apache Software Foundation (ASF) under one or more |
||||
# contributor license agreements. See the NOTICE file distributed with |
||||
# this work for additional information regarding copyright ownership. |
||||
# The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
# (the "License"); you may not use this file except in compliance with |
||||
# the License. You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
# |
||||
|
||||
|
||||
msg=$1 |
||||
content=$2 |
||||
|
||||
# Write your specific logic here |
||||
|
||||
# Set the exit code according to your execution result, and alert needs to use it to judge the status of this alarm result |
||||
exit 0 |
@ -1,78 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
<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"> |
||||
<parent> |
||||
<artifactId>dolphinscheduler-alert-plugin</artifactId> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<version>1.3.4-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-alert-wechat</artifactId> |
||||
<packaging>dolphinscheduler-plugin</packaging> |
||||
<dependencies> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-spi</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>ch.qos.logback</groupId> |
||||
<artifactId>logback-classic</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.httpcomponents</groupId> |
||||
<artifactId>httpclient</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.fasterxml.jackson.core</groupId> |
||||
<artifactId>jackson-databind</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>junit</groupId> |
||||
<artifactId>junit</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.mockito</groupId> |
||||
<artifactId>mockito-core</artifactId> |
||||
<type>jar</type> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
|
||||
</dependencies> |
||||
|
||||
<build> |
||||
<finalName>dolphinscheduler-alert-wechat-${project.version}</finalName> |
||||
</build> |
||||
</project> |
@ -1,41 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.wechat; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertData; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertInfo; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* WeChatAlertChannel |
||||
*/ |
||||
public class WeChatAlertChannel implements AlertChannel { |
||||
|
||||
@Override |
||||
public AlertResult process(AlertInfo info) { |
||||
AlertData alertData = info.getAlertData(); |
||||
String alertParams = info.getAlertParams(); |
||||
Map<String, String> paramsMap = PluginParamsTransfer.getPluginParamsMap(alertParams); |
||||
return new WeChatSender(paramsMap).sendEnterpriseWeChat(alertData.getTitle(), alertData.getContent()); |
||||
|
||||
} |
||||
} |
@ -1,94 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.wechat; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertConstants; |
||||
import org.apache.dolphinscheduler.spi.alert.ShowType; |
||||
import org.apache.dolphinscheduler.spi.params.InputParam; |
||||
import org.apache.dolphinscheduler.spi.params.RadioParam; |
||||
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.params.base.Validate; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* WeChatAlertChannelFactory |
||||
*/ |
||||
public class WeChatAlertChannelFactory implements AlertChannelFactory { |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return "WeChat"; |
||||
} |
||||
|
||||
@Override |
||||
public List<PluginParams> getParams() { |
||||
InputParam corpIdParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_CORP_ID) |
||||
.setPlaceholder("please input corp id ") |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam secretParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_SECRET) |
||||
.setPlaceholder("please input secret ") |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam usersParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USERS, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_USERS) |
||||
.setPlaceholder("please input users ") |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam userSendMsgParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_USER_SEND_MSG) |
||||
.setPlaceholder("please input corp id ") |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
InputParam agentIdParam = InputParam.newBuilder(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_AGENT_ID, WeChatAlertParamsConstants.ENTERPRISE_WE_CHAT_AGENT_ID) |
||||
.setPlaceholder("please input agent id ") |
||||
.addValidate(Validate.newBuilder() |
||||
.setRequired(true) |
||||
.build()) |
||||
.build(); |
||||
|
||||
RadioParam showType = RadioParam.newBuilder(AlertConstants.SHOW_TYPE, AlertConstants.SHOW_TYPE) |
||||
.addParamsOptions(new ParamsOptions(ShowType.TABLE.getDescp(), ShowType.TABLE.getDescp(), false)) |
||||
.addParamsOptions(new ParamsOptions(ShowType.TEXT.getDescp(), ShowType.TEXT.getDescp(), false)) |
||||
.setValue(ShowType.TABLE.getDescp()) |
||||
.addValidate(Validate.newBuilder().setRequired(true).build()) |
||||
.build(); |
||||
|
||||
return Arrays.asList(corpIdParam, secretParam, usersParam, userSendMsgParam, agentIdParam, showType); |
||||
} |
||||
|
||||
@Override |
||||
public AlertChannel create() { |
||||
return new WeChatAlertChannel(); |
||||
} |
||||
} |
@ -1,34 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.wechat; |
||||
|
||||
/** |
||||
* WeChatAlertConstants |
||||
*/ |
||||
public class WeChatAlertConstants { |
||||
|
||||
static final String MARKDOWN_QUOTE = ">"; |
||||
|
||||
static final String MARKDOWN_ENTER = "\n"; |
||||
|
||||
static final String CHARSET = "UTF-8"; |
||||
|
||||
static final String WE_CHAT_PUSH_URL = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}"; |
||||
|
||||
static final String WE_CHAT_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={secret}"; |
||||
} |
@ -1,56 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.wechat; |
||||
|
||||
/** |
||||
* WeChatAlertParamsConstants |
||||
*/ |
||||
public class WeChatAlertParamsConstants { |
||||
|
||||
|
||||
static final String ENTERPRISE_WE_CHAT_CORP_ID = "corp.id"; |
||||
|
||||
static final String NAME_ENTERPRISE_WE_CHAT_CORP_ID = "corpId"; |
||||
|
||||
|
||||
static final String ENTERPRISE_WE_CHAT_SECRET = "secret"; |
||||
|
||||
static final String NAME_ENTERPRISE_WE_CHAT_SECRET = "secret"; |
||||
|
||||
static final String ENTERPRISE_WE_CHAT_TEAM_SEND_MSG = "team.send.msg"; |
||||
|
||||
static final String NAME_ENTERPRISE_WE_CHAT_TEAM_SEND_MSG = "teamSendMsg"; |
||||
|
||||
|
||||
static final String ENTERPRISE_WE_CHAT_USER_SEND_MSG = "user.send.msg"; |
||||
|
||||
static final String NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG = "userSendMsg"; |
||||
|
||||
|
||||
static final String ENTERPRISE_WE_CHAT_AGENT_ID = "agent.id"; |
||||
|
||||
static final String NAME_ENTERPRISE_WE_CHAT_AGENT_ID = "agentId"; |
||||
|
||||
|
||||
static final String ENTERPRISE_WE_CHAT_USERS = "users"; |
||||
|
||||
|
||||
static final String NAME_ENTERPRISE_WE_CHAT_USERS = "users"; |
||||
|
||||
|
||||
} |
@ -1,34 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.wechat; |
||||
|
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
|
||||
/** |
||||
* WeChatAlertPlugin |
||||
*/ |
||||
public class WeChatAlertPlugin implements DolphinSchedulerPlugin { |
||||
|
||||
@Override |
||||
public Iterable<AlertChannelFactory> getAlertChannelFactorys() { |
||||
return ImmutableList.of(new WeChatAlertChannelFactory()); |
||||
} |
||||
} |
@ -1,335 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.wechat; |
||||
|
||||
import static java.util.Objects.requireNonNull; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertConstants; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.alert.ShowType; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||
|
||||
import org.apache.http.HttpEntity; |
||||
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
import org.apache.http.client.methods.HttpGet; |
||||
import org.apache.http.client.methods.HttpPost; |
||||
import org.apache.http.entity.StringEntity; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.apache.http.impl.client.HttpClients; |
||||
import org.apache.http.util.EntityUtils; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Arrays; |
||||
import java.util.Collection; |
||||
import java.util.HashMap; |
||||
import java.util.Iterator; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Map.Entry; |
||||
import java.util.Set; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* WeChatSender |
||||
*/ |
||||
public class WeChatSender { |
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(WeChatSender.class); |
||||
|
||||
private String weChatAgentId; |
||||
|
||||
private String weChatUsers; |
||||
|
||||
private String weChatTeamSendMsg; |
||||
|
||||
private String weChatUserSendMsg; |
||||
|
||||
private String weChatTokenUrlReplace; |
||||
|
||||
private String weChatToken; |
||||
|
||||
private String showType; |
||||
|
||||
|
||||
private static final String agentIdRegExp = "{agentId}"; |
||||
private static final String msgRegExp = "{msg}"; |
||||
private static final String userRegExp = "{toUser}"; |
||||
private static final String corpIdRegex = "{corpId}"; |
||||
private static final String secretRegex = "{secret}"; |
||||
private static final String toPartyRegex = "{toParty}"; |
||||
private static final String toUserRegex = "{toUser}"; |
||||
private static final String tokenRegex = "{token}"; |
||||
|
||||
WeChatSender(Map<String, String> config) { |
||||
weChatAgentId = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_AGENT_ID); |
||||
weChatUsers = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USERS); |
||||
String weChatCorpId = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID); |
||||
String weChatSecret = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET); |
||||
String weChatTokenUrl = WeChatAlertConstants.WE_CHAT_TOKEN_URL; |
||||
weChatTeamSendMsg = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_TEAM_SEND_MSG); |
||||
weChatUserSendMsg = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG); |
||||
showType = config.get(AlertConstants.SHOW_TYPE); |
||||
requireNonNull(showType, AlertConstants.SHOW_TYPE + " must not null"); |
||||
weChatTokenUrlReplace = weChatTokenUrl |
||||
.replace(corpIdRegex, weChatCorpId) |
||||
.replace(secretRegex, weChatSecret); |
||||
weChatToken = getToken(); |
||||
} |
||||
|
||||
/** |
||||
* make user multi user message |
||||
* |
||||
* @param toUser the toUser |
||||
* @param agentId the agentId |
||||
* @param msg the msg |
||||
* @return Enterprise WeChat send message |
||||
*/ |
||||
private String makeUserSendMsg(Collection<String> toUser, String agentId, String msg) { |
||||
String listUser = mkString(toUser); |
||||
return weChatUserSendMsg.replace(userRegExp, listUser) |
||||
.replace(agentIdRegExp, agentId) |
||||
.replace(msgRegExp, msg); |
||||
} |
||||
|
||||
/** |
||||
* send Enterprise WeChat |
||||
* |
||||
* @return Enterprise WeChat resp, demo: {"errcode":0,"errmsg":"ok","invaliduser":""} |
||||
* @throws Exception the Exception |
||||
*/ |
||||
public AlertResult sendEnterpriseWeChat(String title, String content) { |
||||
AlertResult alertResult; |
||||
List<String> userList = Arrays.asList(weChatUsers.split(",")); |
||||
String data = markdownByAlert(title, content); |
||||
String msg = makeUserSendMsg(userList, weChatAgentId, data); |
||||
if (null == weChatToken) { |
||||
alertResult = new AlertResult(); |
||||
alertResult.setMessage("send we chat alert fail,get weChat token error"); |
||||
alertResult.setStatus("false"); |
||||
return alertResult; |
||||
} |
||||
String enterpriseWeChatPushUrlReplace = WeChatAlertConstants.WE_CHAT_PUSH_URL.replace(tokenRegex, weChatToken); |
||||
|
||||
try { |
||||
return checkWeChatSendMsgResult(post(enterpriseWeChatPushUrlReplace, msg)); |
||||
} catch (Exception e) { |
||||
logger.info("send we chat alert msg exception : {}", e.getMessage()); |
||||
alertResult = new AlertResult(); |
||||
alertResult.setMessage("send we chat alert fail"); |
||||
alertResult.setStatus("false"); |
||||
} |
||||
return alertResult; |
||||
} |
||||
|
||||
private static String post(String url, String data) throws IOException { |
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) { |
||||
HttpPost httpPost = new HttpPost(url); |
||||
httpPost.setEntity(new StringEntity(data, WeChatAlertConstants.CHARSET)); |
||||
CloseableHttpResponse response = httpClient.execute(httpPost); |
||||
String resp; |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
resp = EntityUtils.toString(entity, WeChatAlertConstants.CHARSET); |
||||
EntityUtils.consume(entity); |
||||
} finally { |
||||
response.close(); |
||||
} |
||||
logger.info("Enterprise WeChat send [{}], param:{}, resp:{}", |
||||
url, data, resp); |
||||
return resp; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* convert table to markdown style |
||||
* |
||||
* @param title the title |
||||
* @param content the content |
||||
* @return markdown table content |
||||
*/ |
||||
private static String markdownTable(String title, String content) { |
||||
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class); |
||||
if (null == mapItemsList || mapItemsList.isEmpty()) { |
||||
logger.error("itemsList is null"); |
||||
throw new RuntimeException("itemsList is null"); |
||||
} |
||||
StringBuilder contents = new StringBuilder(200); |
||||
for (LinkedHashMap mapItems : mapItemsList) { |
||||
Set<Entry<String, Object>> entries = mapItems.entrySet(); |
||||
Iterator<Entry<String, Object>> iterator = entries.iterator(); |
||||
StringBuilder t = new StringBuilder(String.format("`%s`%s", title, WeChatAlertConstants.MARKDOWN_ENTER)); |
||||
|
||||
while (iterator.hasNext()) { |
||||
|
||||
Map.Entry<String, Object> entry = iterator.next(); |
||||
t.append(WeChatAlertConstants.MARKDOWN_QUOTE); |
||||
t.append(entry.getKey()).append(":").append(entry.getValue()); |
||||
t.append(WeChatAlertConstants.MARKDOWN_ENTER); |
||||
} |
||||
contents.append(t); |
||||
} |
||||
|
||||
return contents.toString(); |
||||
} |
||||
|
||||
/** |
||||
* convert text to markdown style |
||||
* |
||||
* @param title the title |
||||
* @param content the content |
||||
* @return markdown text |
||||
*/ |
||||
private static String markdownText(String title, String content) { |
||||
if (StringUtils.isNotEmpty(content)) { |
||||
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class); |
||||
if (null == mapItemsList || mapItemsList.isEmpty()) { |
||||
logger.error("itemsList is null"); |
||||
throw new RuntimeException("itemsList is null"); |
||||
} |
||||
|
||||
StringBuilder contents = new StringBuilder(100); |
||||
contents.append(String.format("`%s`%n", title)); |
||||
for (LinkedHashMap mapItems : mapItemsList) { |
||||
|
||||
Set<Map.Entry<String, Object>> entries = mapItems.entrySet(); |
||||
for (Entry<String, Object> entry : entries) { |
||||
contents.append(WeChatAlertConstants.MARKDOWN_QUOTE); |
||||
contents.append(entry.getKey()).append(":").append(entry.getValue()); |
||||
contents.append(WeChatAlertConstants.MARKDOWN_ENTER); |
||||
} |
||||
|
||||
} |
||||
return contents.toString(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Determine the mardown style based on the show type of the alert |
||||
* |
||||
* @return the markdown alert table/text |
||||
*/ |
||||
private String markdownByAlert(String title, String content) { |
||||
String result = ""; |
||||
if (showType.equals(ShowType.TABLE.getDescp())) { |
||||
result = markdownTable(title, content); |
||||
} else if (showType.equals(ShowType.TEXT.getDescp())) { |
||||
result = markdownText(title, content); |
||||
} |
||||
return result; |
||||
|
||||
} |
||||
|
||||
private String getToken() { |
||||
try { |
||||
return get(weChatTokenUrlReplace); |
||||
} catch (IOException e) { |
||||
logger.info("we chat alert get token error{}", e.getMessage()); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private static String get(String url) throws IOException { |
||||
String resp; |
||||
|
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) { |
||||
HttpGet httpGet = new HttpGet(url); |
||||
try (CloseableHttpResponse response = httpClient.execute(httpGet)) { |
||||
HttpEntity entity = response.getEntity(); |
||||
resp = EntityUtils.toString(entity, WeChatAlertConstants.CHARSET); |
||||
EntityUtils.consume(entity); |
||||
} |
||||
|
||||
HashMap map = JSONUtils.parseObject(resp, HashMap.class); |
||||
if (map != null && null != map.get("access_token")) { |
||||
return map.get("access_token").toString(); |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static String mkString(Iterable<String> list) { |
||||
|
||||
if (null == list || StringUtils.isEmpty("|")) { |
||||
return null; |
||||
} |
||||
|
||||
StringBuilder sb = new StringBuilder(); |
||||
boolean first = true; |
||||
for (String item : list) { |
||||
if (first) { |
||||
first = false; |
||||
} else { |
||||
sb.append("|"); |
||||
} |
||||
sb.append(item); |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
|
||||
public static class WeChatSendMsgResponse { |
||||
private Integer errcode; |
||||
private String errmsg; |
||||
|
||||
public Integer getErrcode() { |
||||
return errcode; |
||||
} |
||||
|
||||
public void setErrcode(Integer errcode) { |
||||
this.errcode = errcode; |
||||
} |
||||
|
||||
public String getErrmsg() { |
||||
return errmsg; |
||||
} |
||||
|
||||
public void setErrmsg(String errmsg) { |
||||
this.errmsg = errmsg; |
||||
} |
||||
} |
||||
|
||||
private static AlertResult checkWeChatSendMsgResult(String result) { |
||||
AlertResult alertResult = new AlertResult(); |
||||
alertResult.setStatus("false"); |
||||
|
||||
if (null == result) { |
||||
alertResult.setMessage("we chat send fail"); |
||||
logger.info("send we chat msg error,resp is null"); |
||||
return alertResult; |
||||
} |
||||
WeChatSendMsgResponse sendMsgResponse = JSONUtils.parseObject(result, WeChatSendMsgResponse.class); |
||||
if (null == sendMsgResponse) { |
||||
alertResult.setMessage("we chat send fail"); |
||||
logger.info("send we chat msg error,resp error"); |
||||
return alertResult; |
||||
} |
||||
if (sendMsgResponse.errcode == 0) { |
||||
alertResult.setStatus("true"); |
||||
alertResult.setMessage("we chat alert send success"); |
||||
return alertResult; |
||||
} |
||||
alertResult.setStatus("false"); |
||||
alertResult.setMessage(sendMsgResponse.getErrmsg()); |
||||
return alertResult; |
||||
} |
||||
} |
@ -1,48 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.wechat; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* WeChatAlertChannelFactoryTest |
||||
*/ |
||||
public class WeChatAlertChannelFactoryTest { |
||||
|
||||
@Test |
||||
public void testGetParams() { |
||||
WeChatAlertChannelFactory weChatAlertChannelFactory = new WeChatAlertChannelFactory(); |
||||
List<PluginParams> params = weChatAlertChannelFactory.getParams(); |
||||
JSONUtils.toJsonString(params); |
||||
Assert.assertEquals(6, params.size()); |
||||
} |
||||
|
||||
@Test |
||||
public void testCreate() { |
||||
WeChatAlertChannelFactory dingTalkAlertChannelFactory = new WeChatAlertChannelFactory(); |
||||
AlertChannel alertChannel = dingTalkAlertChannelFactory.create(); |
||||
Assert.assertNotNull(alertChannel); |
||||
} |
||||
} |
@ -1,89 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.alert.wechat; |
||||
|
||||
import org.apache.dolphinscheduler.spi.alert.AlertConstants; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
import org.apache.dolphinscheduler.spi.alert.ShowType; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* WeChatSenderTest |
||||
*/ |
||||
public class WeChatSenderTest { |
||||
|
||||
private static Map<String, String> weChatConfig = new HashMap<>(); |
||||
|
||||
private String content = "[{\"id\":\"69\"," |
||||
+ |
||||
"\"name\":\"UserBehavior-0--1193959466\"," |
||||
+ |
||||
"\"Job name\":\"Start workflow\"," |
||||
+ |
||||
"\"State\":\"SUCCESS\"," |
||||
+ |
||||
"\"Recovery\":\"NO\"," |
||||
+ |
||||
"\"Run time\":\"1\"," |
||||
+ |
||||
"\"Start time\": \"2018-08-06 10:31:34.0\"," |
||||
+ |
||||
"\"End time\": \"2018-08-06 10:31:49.0\"," |
||||
+ |
||||
"\"Host\": \"192.168.xx.xx\"," |
||||
+ |
||||
"\"Notify group\" :\"4\"}]"; |
||||
|
||||
@Before |
||||
public void initDingTalkConfig() { |
||||
// Just for this test, I will delete these configurations before this PR is merged
|
||||
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_AGENT_ID, "100000"); |
||||
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID, "NAME_ENTERPRISE_WE_CHAT_CORP_ID"); |
||||
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET, "NAME_ENTERPRISE_WE_CHAT_SECRET"); |
||||
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG, "{\"touser\":\"{toUser}\",\"agentid\":{agentId}" |
||||
+ |
||||
",\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"{msg}\"}}" |
||||
); |
||||
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USERS, "Kris"); |
||||
weChatConfig.put(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_TEAM_SEND_MSG, "msg"); |
||||
weChatConfig.put(AlertConstants.SHOW_TYPE, ShowType.TABLE.getDescp()); |
||||
} |
||||
|
||||
@Test |
||||
public void testSendWeChatTableMsg() { |
||||
WeChatSender weChatSender = new WeChatSender(weChatConfig); |
||||
|
||||
AlertResult alertResult = weChatSender.sendEnterpriseWeChat("test", content); |
||||
Assert.assertEquals("false", alertResult.getStatus()); |
||||
} |
||||
|
||||
@Test |
||||
public void testSendWeChatTextMsg() { |
||||
weChatConfig.put(AlertConstants.SHOW_TYPE, ShowType.TEXT.getDescp()); |
||||
WeChatSender weChatSender = new WeChatSender(weChatConfig); |
||||
AlertResult alertResult = weChatSender.sendEnterpriseWeChat("test", content); |
||||
Assert.assertEquals("false", alertResult.getStatus()); |
||||
} |
||||
|
||||
} |
@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
<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"> |
||||
<parent> |
||||
<artifactId>dolphinscheduler</artifactId> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<version>1.3.4-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-alert-plugin</artifactId> |
||||
<packaging>pom</packaging> |
||||
|
||||
<modules> |
||||
<module>dolphinscheduler-alert-email</module> |
||||
<module>dolphinscheduler-alert-wechat</module> |
||||
<module>dolphinscheduler-alert-dingtalk</module> |
||||
<module>dolphinscheduler-alert-script</module> |
||||
<module>dolphinscheduler-alert-http</module> |
||||
</modules> |
||||
|
||||
|
||||
</project> |
@ -1,55 +1,55 @@
|
||||
///*
|
||||
// * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
// * contributor license agreements. See the NOTICE file distributed with
|
||||
// * this work for additional information regarding copyright ownership.
|
||||
// * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
// * (the "License"); you may not use this file except in compliance with
|
||||
// * the License. You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// */
|
||||
//package org.apache.dolphinscheduler.alert.manager;
|
||||
//
|
||||
//import org.apache.dolphinscheduler.alert.utils.MailUtils;
|
||||
//
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//
|
||||
///**
|
||||
// * email send manager
|
||||
// */
|
||||
//public class EmailManager {
|
||||
// /**
|
||||
// * email send
|
||||
// * @param receiversList the receiver list
|
||||
// * @param receiversCcList the cc List
|
||||
// * @param title the title
|
||||
// * @param content the content
|
||||
// * @param showType the showType
|
||||
// * @return the send result
|
||||
// */
|
||||
// public Map<String,Object> send(List<String> receiversList,List<String> receiversCcList,String title,String content,String showType){
|
||||
//
|
||||
// return MailUtils.sendMails(receiversList, receiversCcList, title, content, showType);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * msg send
|
||||
// * @param receiversList the receiver list
|
||||
// * @param title the title
|
||||
// * @param content the content
|
||||
// * @param showType the showType
|
||||
// * @return the send result
|
||||
// */
|
||||
// public Map<String,Object> send(List<String> receiversList,String title,String content,String showType){
|
||||
//
|
||||
// return MailUtils.sendMails(receiversList,title, content, showType);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.apache.dolphinscheduler.alert.manager; |
||||
|
||||
import org.apache.dolphinscheduler.alert.utils.MailUtils; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* email send manager |
||||
*/ |
||||
public class EmailManager { |
||||
/** |
||||
* email send |
||||
* @param receiversList the receiver list |
||||
* @param receiversCcList the cc List |
||||
* @param title the title |
||||
* @param content the content |
||||
* @param showType the showType |
||||
* @return the send result |
||||
*/ |
||||
public Map<String,Object> send(List<String> receiversList,List<String> receiversCcList,String title,String content,String showType){ |
||||
|
||||
return MailUtils.sendMails(receiversList, receiversCcList, title, content, showType); |
||||
} |
||||
|
||||
/** |
||||
* msg send |
||||
* @param receiversList the receiver list |
||||
* @param title the title |
||||
* @param content the content |
||||
* @param showType the showType |
||||
* @return the send result |
||||
*/ |
||||
public Map<String,Object> send(List<String> receiversList,String title,String content,String showType){ |
||||
|
||||
return MailUtils.sendMails(receiversList,title, content, showType); |
||||
} |
||||
|
||||
} |
||||
|
@ -0,0 +1,59 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.apache.dolphinscheduler.alert.manager; |
||||
|
||||
import org.apache.dolphinscheduler.alert.utils.Constants; |
||||
import org.apache.dolphinscheduler.alert.utils.EnterpriseWeChatUtils; |
||||
import org.apache.dolphinscheduler.plugin.model.AlertInfo; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Arrays; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Enterprise WeChat Manager |
||||
*/ |
||||
public class EnterpriseWeChatManager { |
||||
private static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatManager.class); |
||||
/** |
||||
* Enterprise We Chat send |
||||
* @param alertInfo the alert info |
||||
* @param token the token |
||||
* @return the send result |
||||
*/ |
||||
public Map<String,Object> send(AlertInfo alertInfo, String token){ |
||||
Map<String,Object> retMap = new HashMap<>(); |
||||
retMap.put(Constants.STATUS, false); |
||||
String agentId = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_AGENT_ID; |
||||
String users = EnterpriseWeChatUtils.ENTERPRISE_WE_CHAT_USERS; |
||||
List<String> userList = Arrays.asList(users.split(",")); |
||||
logger.info("send message {}", alertInfo.getAlertData().getTitle()); |
||||
String msg = EnterpriseWeChatUtils.makeUserSendMsg(userList, agentId,EnterpriseWeChatUtils.markdownByAlert(alertInfo.getAlertData())); |
||||
try { |
||||
EnterpriseWeChatUtils.sendEnterpriseWeChat(Constants.UTF_8, msg, token); |
||||
} catch (IOException e) { |
||||
logger.error(e.getMessage(),e); |
||||
} |
||||
retMap.put(Constants.STATUS, true); |
||||
return retMap; |
||||
} |
||||
|
||||
} |
@ -1,29 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.plugin; |
||||
|
||||
import org.apache.dolphinscheduler.dao.DaoFactory; |
||||
import org.apache.dolphinscheduler.dao.PluginDao; |
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
|
||||
public abstract class AbstractDolphinPluginManager { |
||||
|
||||
protected PluginDao pluginDao = DaoFactory.getDaoInstance(PluginDao.class); |
||||
|
||||
public abstract void installPlugin(DolphinSchedulerPlugin dolphinSchedulerPlugin); |
||||
} |
@ -1,99 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.plugin; |
||||
|
||||
import static java.lang.String.format; |
||||
import static java.util.Objects.requireNonNull; |
||||
|
||||
import static com.google.common.base.Preconditions.checkState; |
||||
|
||||
import org.apache.dolphinscheduler.common.enums.PluginType; |
||||
import org.apache.dolphinscheduler.dao.entity.PluginDefine; |
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannelFactory; |
||||
import org.apache.dolphinscheduler.spi.classloader.ThreadContextClassLoader; |
||||
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer; |
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* load the configured alert plugin and manager them |
||||
*/ |
||||
public class AlertPluginManager extends AbstractDolphinPluginManager { |
||||
private static final Logger logger = LoggerFactory.getLogger(AlertPluginManager.class); |
||||
|
||||
private final Map<String, AlertChannelFactory> alertChannelFactoryMap = new ConcurrentHashMap<>(); |
||||
private final Map<String, AlertChannel> alertChannelMap = new ConcurrentHashMap<>(); |
||||
|
||||
public void addAlertChannelFactory(AlertChannelFactory alertChannelFactory) { |
||||
requireNonNull(alertChannelFactory, "alertChannelFactory is null"); |
||||
|
||||
if (alertChannelFactoryMap.putIfAbsent(alertChannelFactory.getName(), alertChannelFactory) != null) { |
||||
throw new IllegalArgumentException(format("Alert Plugin '{}' is already registered", alertChannelFactory.getName())); |
||||
} |
||||
|
||||
try { |
||||
loadAlertChannel(alertChannelFactory.getName()); |
||||
} catch (Exception e) { |
||||
throw new IllegalArgumentException(format("Alert Plugin '{}' is can not load .", alertChannelFactory.getName())); |
||||
} |
||||
} |
||||
|
||||
protected void loadAlertChannel(String name) { |
||||
requireNonNull(name, "name is null"); |
||||
|
||||
AlertChannelFactory alertChannelFactory = alertChannelFactoryMap.get(name); |
||||
checkState(alertChannelFactory != null, "Alert Plugin {} is not registered", name); |
||||
|
||||
try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(alertChannelFactory.getClass().getClassLoader())) { |
||||
AlertChannel alertChannel = alertChannelFactory.create(); |
||||
this.alertChannelMap.put(name, alertChannel); |
||||
} |
||||
|
||||
logger.info("-- Loaded Alert Plugin {} --", name); |
||||
} |
||||
|
||||
public Map<String, AlertChannelFactory> getAlertChannelFactoryMap() { |
||||
return alertChannelFactoryMap; |
||||
} |
||||
|
||||
public Map<String, AlertChannel> getAlertChannelMap() { |
||||
return alertChannelMap; |
||||
} |
||||
|
||||
@Override |
||||
public void installPlugin(DolphinSchedulerPlugin dolphinSchedulerPlugin) { |
||||
for (AlertChannelFactory alertChannelFactory : dolphinSchedulerPlugin.getAlertChannelFactorys()) { |
||||
logger.info("Registering Alert Plugin '{}'", alertChannelFactory.getName()); |
||||
this.addAlertChannelFactory(alertChannelFactory); |
||||
List<PluginParams> params = alertChannelFactory.getParams(); |
||||
String nameEn = alertChannelFactory.getName(); |
||||
String paramsJson = PluginParamsTransfer.transferParamsToJson(params); |
||||
|
||||
PluginDefine pluginDefine = new PluginDefine(nameEn, PluginType.ALERT.getDesc(), paramsJson); |
||||
pluginDao.addOrUpdatePluginDefine(pluginDefine); |
||||
} |
||||
} |
||||
} |
@ -1,139 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.plugin; |
||||
|
||||
import static java.util.Objects.requireNonNull; |
||||
|
||||
import java.io.IOException; |
||||
import java.lang.reflect.InvocationTargetException; |
||||
import java.lang.reflect.Method; |
||||
import java.net.URL; |
||||
import java.net.URLClassLoader; |
||||
import java.util.Enumeration; |
||||
import java.util.List; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
import com.google.common.collect.Iterables; |
||||
|
||||
class DolphinPluginClassLoader |
||||
extends URLClassLoader { |
||||
private static final ClassLoader PLATFORM_CLASS_LOADER = findPlatformClassLoader(); |
||||
|
||||
private final ClassLoader spiClassLoader; |
||||
private final List<String> spiPackages; |
||||
private final List<String> spiResources; |
||||
|
||||
public DolphinPluginClassLoader( |
||||
List<URL> urls, |
||||
ClassLoader spiClassLoader, |
||||
Iterable<String> spiPackages) { |
||||
this(urls, |
||||
spiClassLoader, |
||||
spiPackages, |
||||
Iterables.transform(spiPackages, DolphinPluginClassLoader::classNameToResource)); |
||||
} |
||||
|
||||
private DolphinPluginClassLoader( |
||||
List<URL> urls, |
||||
ClassLoader spiClassLoader, |
||||
Iterable<String> spiPackages, |
||||
Iterable<String> spiResources) { |
||||
// plugins should not have access to the system (application) class loader
|
||||
super(urls.toArray(new URL[urls.size()]), PLATFORM_CLASS_LOADER); |
||||
this.spiClassLoader = requireNonNull(spiClassLoader, "spiClassLoader is null"); |
||||
this.spiPackages = ImmutableList.copyOf(spiPackages); |
||||
this.spiResources = ImmutableList.copyOf(spiResources); |
||||
} |
||||
|
||||
@Override |
||||
protected Class<?> loadClass(String name, boolean resolve) |
||||
throws ClassNotFoundException { |
||||
// grab the magic lock
|
||||
synchronized (getClassLoadingLock(name)) { |
||||
// Check if class is in the loaded classes cache
|
||||
Class<?> cachedClass = findLoadedClass(name); |
||||
if (cachedClass != null) { |
||||
return resolveClass(cachedClass, resolve); |
||||
} |
||||
|
||||
// If this is an SPI class, only check SPI class loader
|
||||
if (isSpiClass(name)) { |
||||
return resolveClass(spiClassLoader.loadClass(name), resolve); |
||||
} |
||||
|
||||
// Look for class locally
|
||||
return super.loadClass(name, resolve); |
||||
} |
||||
} |
||||
|
||||
private Class<?> resolveClass(Class<?> clazz, boolean resolve) { |
||||
if (resolve) { |
||||
resolveClass(clazz); |
||||
} |
||||
return clazz; |
||||
} |
||||
|
||||
@Override |
||||
public URL getResource(String name) { |
||||
// If this is an SPI resource, only check SPI class loader
|
||||
if (isSpiResource(name)) { |
||||
return spiClassLoader.getResource(name); |
||||
} |
||||
|
||||
// Look for resource locally
|
||||
return super.getResource(name); |
||||
} |
||||
|
||||
@Override |
||||
public Enumeration<URL> getResources(String name) |
||||
throws IOException { |
||||
// If this is an SPI resource, use SPI resources
|
||||
if (isSpiClass(name)) { |
||||
return spiClassLoader.getResources(name); |
||||
} |
||||
|
||||
// Use local resources
|
||||
return super.getResources(name); |
||||
} |
||||
|
||||
private boolean isSpiClass(String name) { |
||||
return spiPackages.stream().anyMatch(name::startsWith); |
||||
} |
||||
|
||||
private boolean isSpiResource(String name) { |
||||
return spiResources.stream().anyMatch(name::startsWith); |
||||
} |
||||
|
||||
private static String classNameToResource(String className) { |
||||
return className.replace('.', '/'); |
||||
} |
||||
|
||||
@SuppressWarnings("JavaReflectionMemberAccess") |
||||
private static ClassLoader findPlatformClassLoader() { |
||||
try { |
||||
// use platform class loader on Java 9
|
||||
Method method = ClassLoader.class.getMethod("getPlatformClassLoader"); |
||||
return (ClassLoader) method.invoke(null); |
||||
} catch (NoSuchMethodException ignored) { |
||||
// use null class loader on Java 8
|
||||
return null; |
||||
} catch (IllegalAccessException | InvocationTargetException e) { |
||||
throw new AssertionError(e); |
||||
} |
||||
} |
||||
} |
@ -1,139 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.plugin; |
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8; |
||||
import static java.nio.file.Files.createDirectories; |
||||
import static java.nio.file.Files.walkFileTree; |
||||
|
||||
import static com.google.common.io.ByteStreams.toByteArray; |
||||
|
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStreamWriter; |
||||
import java.io.UncheckedIOException; |
||||
import java.io.Writer; |
||||
import java.nio.file.FileVisitResult; |
||||
import java.nio.file.Path; |
||||
import java.nio.file.SimpleFileVisitor; |
||||
import java.nio.file.attribute.BasicFileAttributes; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import org.objectweb.asm.ClassReader; |
||||
import org.sonatype.aether.artifact.Artifact; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
import com.google.common.collect.ImmutableSet; |
||||
|
||||
/** |
||||
* The role of this class is to load the plugin class during development |
||||
*/ |
||||
final class DolphinPluginDiscovery { |
||||
private static final String JAVA_CLASS_FILE_SUFFIX = ".class"; |
||||
private static final String PLUGIN_SERVICES_FILE = "META-INF/services/" + DolphinSchedulerPlugin.class.getName(); |
||||
|
||||
private DolphinPluginDiscovery() { |
||||
} |
||||
|
||||
public static Set<String> discoverPluginsFromArtifact(Artifact artifact, ClassLoader classLoader) |
||||
throws IOException { |
||||
if (!artifact.getExtension().equals("dolphinscheduler-plugin")) { |
||||
throw new RuntimeException("Unexpected extension for main artifact: " + artifact); |
||||
} |
||||
|
||||
File file = artifact.getFile(); |
||||
if (!file.getPath().endsWith("/target/classes")) { |
||||
throw new RuntimeException("Unexpected file for main artifact: " + file); |
||||
} |
||||
if (!file.isDirectory()) { |
||||
throw new RuntimeException("Main artifact file is not a directory: " + file); |
||||
} |
||||
|
||||
if (new File(file, PLUGIN_SERVICES_FILE).exists()) { |
||||
return ImmutableSet.of(); |
||||
} |
||||
|
||||
return listClasses(file.toPath()).stream() |
||||
.filter(name -> classInterfaces(name, classLoader).contains(DolphinSchedulerPlugin.class.getName())) |
||||
.collect(Collectors.toSet()); |
||||
} |
||||
|
||||
public static void writePluginServices(Iterable<String> plugins, File root) |
||||
throws IOException { |
||||
Path path = root.toPath().resolve(PLUGIN_SERVICES_FILE); |
||||
createDirectories(path.getParent()); |
||||
try (Writer out = new OutputStreamWriter(new FileOutputStream(path.toFile()), UTF_8)) { |
||||
for (String plugin : plugins) { |
||||
out.write(plugin + "\n"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static List<String> listClasses(Path base) |
||||
throws IOException { |
||||
ImmutableList.Builder<String> list = ImmutableList.builder(); |
||||
walkFileTree(base, new SimpleFileVisitor<Path>() { |
||||
@Override |
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) { |
||||
if (file.getFileName().toString().endsWith(JAVA_CLASS_FILE_SUFFIX)) { |
||||
String name = file.subpath(base.getNameCount(), file.getNameCount()).toString(); |
||||
list.add(javaName(name.substring(0, name.length() - JAVA_CLASS_FILE_SUFFIX.length()))); |
||||
} |
||||
return FileVisitResult.CONTINUE; |
||||
} |
||||
}); |
||||
return list.build(); |
||||
} |
||||
|
||||
private static List<String> classInterfaces(String name, ClassLoader classLoader) { |
||||
ImmutableList.Builder<String> list = ImmutableList.builder(); |
||||
ClassReader reader = readClass(name, classLoader); |
||||
for (String binaryName : reader.getInterfaces()) { |
||||
list.add(javaName(binaryName)); |
||||
} |
||||
if (reader.getSuperName() != null) { |
||||
list.addAll(classInterfaces(javaName(reader.getSuperName()), classLoader)); |
||||
} |
||||
return list.build(); |
||||
} |
||||
|
||||
private static ClassReader readClass(String name, ClassLoader classLoader) { |
||||
try (InputStream in = classLoader.getResourceAsStream(binaryName(name) + JAVA_CLASS_FILE_SUFFIX)) { |
||||
if (in == null) { |
||||
throw new RuntimeException("Failed to read class: " + name); |
||||
} |
||||
return new ClassReader(toByteArray(in)); |
||||
} catch (IOException e) { |
||||
throw new UncheckedIOException(e); |
||||
} |
||||
} |
||||
|
||||
private static String binaryName(String javaName) { |
||||
return javaName.replace('.', '/'); |
||||
} |
||||
|
||||
private static String javaName(String binaryName) { |
||||
return binaryName.replace('/', '.'); |
||||
} |
||||
} |
@ -1,194 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.plugin; |
||||
|
||||
import static java.lang.String.format; |
||||
import static java.util.Objects.requireNonNull; |
||||
|
||||
import static com.google.common.base.Preconditions.checkState; |
||||
|
||||
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||
import org.apache.dolphinscheduler.spi.classloader.ThreadContextClassLoader; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.net.URL; |
||||
import java.net.URLClassLoader; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.ServiceLoader; |
||||
import java.util.Set; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.sonatype.aether.artifact.Artifact; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
import com.google.common.collect.Ordering; |
||||
|
||||
import io.airlift.resolver.ArtifactResolver; |
||||
|
||||
/** |
||||
* Plugin Loader |
||||
* Load Plugin from pom when development and run server in IDE |
||||
* Load Plugin from the plugin directory when running on the server |
||||
*/ |
||||
public class DolphinPluginLoader { |
||||
private static final Logger logger = LoggerFactory.getLogger(DolphinPluginLoader.class); |
||||
|
||||
/** |
||||
* All third-party jar packages used in the classes which in spi package need to be add |
||||
*/ |
||||
private static final ImmutableList<String> DOLPHIN_SPI_PACKAGES = ImmutableList.<String>builder() |
||||
.add("org.apache.dolphinscheduler.spi.") |
||||
.add("com.fasterxml.jackson.") |
||||
.build(); |
||||
|
||||
private final File installedPluginsDir; |
||||
private final List<String> configPlugins; |
||||
private ArtifactResolver resolver = null; |
||||
private final List<AbstractDolphinPluginManager> dolphinPluginManagerList; |
||||
|
||||
public DolphinPluginLoader(DolphinPluginManagerConfig config, List<AbstractDolphinPluginManager> dolphinPluginManagerList) { |
||||
installedPluginsDir = config.getInstalledPluginsDir(); |
||||
if (config.getPlugins() == null) { |
||||
this.configPlugins = ImmutableList.of(); |
||||
} else { |
||||
this.configPlugins = ImmutableList.copyOf(config.getPlugins()); |
||||
} |
||||
|
||||
this.dolphinPluginManagerList = requireNonNull(dolphinPluginManagerList, "dolphinPluginManagerList is null"); |
||||
if (configPlugins != null && configPlugins.size() > 0) { |
||||
this.resolver = new ArtifactResolver(config.getMavenLocalRepository(), config.getMavenRemoteRepository()); |
||||
} |
||||
} |
||||
|
||||
public void loadPlugins() |
||||
throws Exception { |
||||
for (File file : listPluginDirs(installedPluginsDir)) { |
||||
if (file.isDirectory()) { |
||||
loadPlugin(file.getAbsolutePath()); |
||||
} |
||||
} |
||||
|
||||
for (String plugin : configPlugins) { |
||||
loadPlugin(plugin); |
||||
} |
||||
} |
||||
|
||||
private void loadPlugin(String plugin) |
||||
throws Exception { |
||||
logger.info("-- Loading Alert plugin {} --", plugin); |
||||
URLClassLoader pluginClassLoader = buildPluginClassLoader(plugin); |
||||
try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(pluginClassLoader)) { |
||||
loadPlugin(pluginClassLoader); |
||||
} |
||||
logger.info("-- Finished loading Alert plugin {} --", plugin); |
||||
} |
||||
|
||||
private void loadPlugin(URLClassLoader pluginClassLoader) { |
||||
ServiceLoader<DolphinSchedulerPlugin> serviceLoader = ServiceLoader.load(DolphinSchedulerPlugin.class, pluginClassLoader); |
||||
List<DolphinSchedulerPlugin> plugins = ImmutableList.copyOf(serviceLoader); |
||||
checkState(!plugins.isEmpty(), "No service providers the plugin {}", DolphinSchedulerPlugin.class.getName()); |
||||
for (DolphinSchedulerPlugin plugin : plugins) { |
||||
logger.info("Installing {}", plugin.getClass().getName()); |
||||
for (AbstractDolphinPluginManager dolphinPluginManager : dolphinPluginManagerList) { |
||||
dolphinPluginManager.installPlugin(plugin); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private URLClassLoader buildPluginClassLoader(String plugin) |
||||
throws Exception { |
||||
File file = new File(plugin); |
||||
|
||||
if (!file.isDirectory() && (file.getName().equals("pom.xml") || file.getName().endsWith(".pom"))) { |
||||
return buildPluginClassLoaderFromPom(file); |
||||
} |
||||
if (file.isDirectory()) { |
||||
return buildPluginClassLoaderFromDirectory(file); |
||||
} else { |
||||
throw new IllegalArgumentException(format("plugin must be a pom file or directory {} .", plugin)); |
||||
} |
||||
} |
||||
|
||||
private URLClassLoader buildPluginClassLoaderFromPom(File pomFile) |
||||
throws Exception { |
||||
List<Artifact> artifacts = resolver.resolvePom(pomFile); |
||||
URLClassLoader classLoader = createClassLoader(artifacts, pomFile.getPath()); |
||||
|
||||
Artifact artifact = artifacts.get(0); |
||||
Set<String> plugins = DolphinPluginDiscovery.discoverPluginsFromArtifact(artifact, classLoader); |
||||
if (!plugins.isEmpty()) { |
||||
DolphinPluginDiscovery.writePluginServices(plugins, artifact.getFile()); |
||||
} |
||||
|
||||
return classLoader; |
||||
} |
||||
|
||||
private URLClassLoader buildPluginClassLoaderFromDirectory(File dir) |
||||
throws Exception { |
||||
logger.info("Classpath for {}:", dir.getName()); |
||||
List<URL> urls = new ArrayList<>(); |
||||
for (File file : listPluginDirs(dir)) { |
||||
logger.info(" {}", file); |
||||
urls.add(file.toURI().toURL()); |
||||
} |
||||
return createClassLoader(urls); |
||||
} |
||||
|
||||
private URLClassLoader createClassLoader(List<Artifact> artifacts, String name) |
||||
throws IOException { |
||||
logger.info("Classpath for {}:", name); |
||||
List<URL> urls = new ArrayList<>(); |
||||
for (Artifact artifact : sortArtifacts(artifacts)) { |
||||
if (artifact.getFile() == null) { |
||||
throw new RuntimeException("Could not resolve artifact: " + artifact); |
||||
} |
||||
File file = artifact.getFile().getCanonicalFile(); |
||||
logger.info(" {}", file); |
||||
urls.add(file.toURI().toURL()); |
||||
} |
||||
return createClassLoader(urls); |
||||
} |
||||
|
||||
private URLClassLoader createClassLoader(List<URL> urls) { |
||||
ClassLoader parent = getClass().getClassLoader(); |
||||
return new DolphinPluginClassLoader(urls, parent, DOLPHIN_SPI_PACKAGES); |
||||
} |
||||
|
||||
private static List<File> listPluginDirs(File installedPluginsDir) { |
||||
if (installedPluginsDir != null && installedPluginsDir.isDirectory()) { |
||||
File[] files = installedPluginsDir.listFiles(); |
||||
if (files != null) { |
||||
Arrays.sort(files); |
||||
return ImmutableList.copyOf(files); |
||||
} |
||||
} |
||||
return ImmutableList.of(); |
||||
} |
||||
|
||||
private static List<Artifact> sortArtifacts(List<Artifact> artifacts) { |
||||
List<Artifact> list = new ArrayList<>(artifacts); |
||||
Collections.sort(list, Ordering.natural().nullsLast().onResultOf(Artifact::getFile)); |
||||
return list; |
||||
} |
||||
|
||||
} |
@ -1,121 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.plugin; |
||||
|
||||
import static java.lang.String.format; |
||||
import static java.util.Objects.requireNonNull; |
||||
|
||||
import java.io.File; |
||||
import java.util.List; |
||||
|
||||
import com.google.common.base.Splitter; |
||||
import com.google.common.collect.ImmutableList; |
||||
|
||||
/** |
||||
* Dolphin Scheduler Plugin Manager Config |
||||
*/ |
||||
public class DolphinPluginManagerConfig { |
||||
|
||||
/** |
||||
* The dir of the Alert Plugin in. |
||||
* When AlertServer is running on the server, it will load the Alert Plugin from this directory. |
||||
*/ |
||||
private File installedPluginsDir; |
||||
|
||||
/** |
||||
* The plugin should be load. |
||||
* The installedPluginsDir is empty when we development and run server in IDEA. Then we can config which plugin should be load by param name alert.plugin.binding in the alert.properties file |
||||
*/ |
||||
private List<String> plugins; |
||||
|
||||
/** |
||||
* Development, When AlertServer is running on IDE, AlertPluginLoad can load Alert Plugin from local Repository. |
||||
*/ |
||||
private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository"; |
||||
private List<String> mavenRemoteRepository = ImmutableList.of("http://repo1.maven.org/maven2/"); |
||||
|
||||
public File getInstalledPluginsDir() { |
||||
return installedPluginsDir; |
||||
} |
||||
|
||||
/** |
||||
* @param pluginDir |
||||
*/ |
||||
public DolphinPluginManagerConfig setInstalledPluginsDir(String pluginDir) { |
||||
requireNonNull(pluginDir, "pluginDir can not be null"); |
||||
File pluginDirFile = new File(pluginDir); |
||||
if (!pluginDirFile.exists()) { |
||||
throw new IllegalArgumentException(format("plugin dir not exists ! {}", pluginDirFile.getPath())); |
||||
} |
||||
this.installedPluginsDir = pluginDirFile; |
||||
return this; |
||||
} |
||||
|
||||
public List<String> getPlugins() { |
||||
return plugins; |
||||
} |
||||
|
||||
public DolphinPluginManagerConfig setPlugins(List<String> plugins) { |
||||
this.plugins = plugins; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* When development and run server in IDE, this method can set plugins in alert.properties . |
||||
* Then when you start AlertServer in IDE, the plugin can be load. |
||||
* eg: |
||||
* file: alert.properties |
||||
* alert.plugin=\ |
||||
* ../dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/pom.xml, \ |
||||
* ../dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/pom.xml |
||||
* |
||||
* @param plugins |
||||
* @return |
||||
*/ |
||||
public DolphinPluginManagerConfig setPlugins(String plugins) { |
||||
if (plugins == null) { |
||||
this.plugins = null; |
||||
} else { |
||||
this.plugins = ImmutableList.copyOf(Splitter.on(',').omitEmptyStrings().trimResults().split(plugins)); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public String getMavenLocalRepository() { |
||||
return mavenLocalRepository; |
||||
} |
||||
|
||||
public DolphinPluginManagerConfig setMavenLocalRepository(String mavenLocalRepository) { |
||||
this.mavenLocalRepository = mavenLocalRepository; |
||||
return this; |
||||
} |
||||
|
||||
public List<String> getMavenRemoteRepository() { |
||||
return mavenRemoteRepository; |
||||
} |
||||
|
||||
public DolphinPluginManagerConfig setMavenRemoteRepository(List<String> mavenRemoteRepository) { |
||||
this.mavenRemoteRepository = mavenRemoteRepository; |
||||
return this; |
||||
} |
||||
|
||||
public DolphinPluginManagerConfig setMavenRemoteRepository(String mavenRemoteRepository) { |
||||
this.mavenRemoteRepository = ImmutableList.copyOf(Splitter.on(',').omitEmptyStrings().trimResults().split(mavenRemoteRepository)); |
||||
return this; |
||||
} |
||||
} |
@ -0,0 +1,147 @@
|
||||
/* |
||||
* 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.DingTalkManager; |
||||
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.DingTalkUtils; |
||||
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 java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* EmailAlertPlugin |
||||
* <p> |
||||
* 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(); |
||||
private static final DingTalkManager dingTalkManager = new DingTalkManager(); |
||||
|
||||
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_ID; |
||||
} |
||||
|
||||
@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> receiversList = (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(","); |
||||
receiversList.addAll(Arrays.asList(splits)); |
||||
} |
||||
|
||||
List<String> receiversCcList = new ArrayList<>(); |
||||
// Custom Copier
|
||||
String receiversCc = alert.getReceiversCc(); |
||||
if (StringUtils.isNotEmpty(receiversCc)) { |
||||
String[] splits = receiversCc.split(","); |
||||
receiversCcList.addAll(Arrays.asList(splits)); |
||||
} |
||||
|
||||
if (CollectionUtils.isEmpty(receiversList) && CollectionUtils.isEmpty(receiversCcList)) { |
||||
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(receiversList, receiversCcList, 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); |
||||
} |
||||
} |
||||
|
||||
if (DingTalkUtils.IS_ENABLE_DING_TALK) { |
||||
logger.info("Ding Talk is enable."); |
||||
dingTalkManager.send(info); |
||||
} |
||||
|
||||
} else { |
||||
retMaps.put(Constants.MESSAGE, "alert send error."); |
||||
logger.info("alert send error : {}", retMaps.get(Constants.MESSAGE)); |
||||
} |
||||
|
||||
return retMaps; |
||||
} |
||||
|
||||
} |
@ -1,67 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.processor; |
||||
|
||||
import org.apache.dolphinscheduler.alert.plugin.AlertPluginManager; |
||||
import org.apache.dolphinscheduler.alert.runner.AlertSender; |
||||
import org.apache.dolphinscheduler.common.utils.Preconditions; |
||||
import org.apache.dolphinscheduler.dao.AlertDao; |
||||
import org.apache.dolphinscheduler.dao.PluginDao; |
||||
import org.apache.dolphinscheduler.remote.command.Command; |
||||
import org.apache.dolphinscheduler.remote.command.CommandType; |
||||
import org.apache.dolphinscheduler.remote.command.alert.AlertSendRequestCommand; |
||||
import org.apache.dolphinscheduler.remote.command.alert.AlertSendResponseCommand; |
||||
import org.apache.dolphinscheduler.remote.processor.NettyRequestProcessor; |
||||
import org.apache.dolphinscheduler.remote.utils.JsonSerializer; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import io.netty.channel.Channel; |
||||
|
||||
/** |
||||
* alert request processor |
||||
*/ |
||||
public class AlertRequestProcessor implements NettyRequestProcessor { |
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(AlertRequestProcessor.class); |
||||
private AlertDao alertDao; |
||||
private PluginDao pluginDao; |
||||
private AlertPluginManager alertPluginManager; |
||||
|
||||
public AlertRequestProcessor(AlertDao alertDao, AlertPluginManager alertPluginManager, PluginDao pluginDao) { |
||||
this.alertDao = alertDao; |
||||
this.pluginDao = pluginDao; |
||||
this.alertPluginManager = alertPluginManager; |
||||
} |
||||
|
||||
@Override |
||||
public void process(Channel channel, Command command) { |
||||
Preconditions.checkArgument(CommandType.ALERT_SEND_REQUEST == command.getType(), |
||||
String.format("invalid command type : %s", command.getType())); |
||||
|
||||
AlertSendRequestCommand alertSendRequestCommand = JsonSerializer.deserialize( |
||||
command.getBody(), AlertSendRequestCommand.class); |
||||
logger.info("received command : {}", alertSendRequestCommand); |
||||
|
||||
AlertSender alertSender = new AlertSender(alertDao, alertPluginManager, pluginDao); |
||||
AlertSendResponseCommand alertSendResponseCommand = alertSender.syncHandler(alertSendRequestCommand.getGroupId(), alertSendRequestCommand.getTitle(), alertSendRequestCommand.getContent()); |
||||
channel.writeAndFlush(alertSendResponseCommand.convert2Command(command.getOpaque())); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,141 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.utils; |
||||
|
||||
import org.apache.dolphinscheduler.common.utils.*; |
||||
|
||||
import org.apache.commons.codec.binary.StringUtils; |
||||
import org.apache.http.HttpEntity; |
||||
import org.apache.http.HttpHost; |
||||
import org.apache.http.auth.AuthScope; |
||||
import org.apache.http.auth.UsernamePasswordCredentials; |
||||
import org.apache.http.client.CredentialsProvider; |
||||
import org.apache.http.client.config.RequestConfig; |
||||
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
import org.apache.http.client.methods.HttpPost; |
||||
import org.apache.http.entity.StringEntity; |
||||
import org.apache.http.impl.client.BasicCredentialsProvider; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.apache.http.impl.client.HttpClients; |
||||
import org.apache.http.util.EntityUtils; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* DingTalkUtils utils |
||||
* support send msg to ding talk by robot message push function. |
||||
* support PROXY setting |
||||
*/ |
||||
public class DingTalkUtils { |
||||
public static final Logger logger = LoggerFactory.getLogger(DingTalkUtils.class); |
||||
|
||||
public static final boolean IS_ENABLE_DING_TALK = PropertyUtils.getBoolean(Constants.DINGTALK_ENABLE); |
||||
private static final String DING_TASK_URL = PropertyUtils.getString(Constants.DINGTALK_WEBHOOK); |
||||
private static final String KEYWORD = PropertyUtils.getString(Constants.DINGTALK_KEYWORD); |
||||
private static final Boolean IS_ENABLE_PROXY = PropertyUtils.getBoolean(Constants.DINGTALK_PROXY_ENABLE); |
||||
private static final String PROXY = PropertyUtils.getString(Constants.DINGTALK_PROXY); |
||||
private static final String USER = PropertyUtils.getString(Constants.DINGTALK_USER); |
||||
private static final String PASSWD = PropertyUtils.getString(Constants.DINGTALK_PASSWORD); |
||||
private static final Integer PORT = PropertyUtils.getInt(Constants.DINGTALK_PORT); |
||||
|
||||
private DingTalkUtils() { |
||||
throw new IllegalStateException(DingTalkUtils.class.getName()); |
||||
} |
||||
|
||||
/** |
||||
* send message interface
|
||||
* only support text message format now. |
||||
* |
||||
* @param msg message context to send |
||||
* @param charset charset type |
||||
* @return result of sending msg |
||||
* @throws IOException the IOException |
||||
*/ |
||||
public static String sendDingTalkMsg(String msg, String charset) throws IOException { |
||||
String msgToJson = textToJsonString(msg + "#" + KEYWORD); |
||||
HttpPost httpPost = constructHttpPost(msgToJson, charset); |
||||
|
||||
CloseableHttpClient httpClient; |
||||
if (Boolean.TRUE.equals(IS_ENABLE_PROXY)) { |
||||
httpClient = getProxyClient(); |
||||
RequestConfig rcf = getProxyConfig(); |
||||
httpPost.setConfig(rcf); |
||||
} else { |
||||
httpClient = getDefaultClient(); |
||||
} |
||||
|
||||
try { |
||||
CloseableHttpResponse response = httpClient.execute(httpPost); |
||||
String resp; |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
resp = EntityUtils.toString(entity, charset); |
||||
EntityUtils.consume(entity); |
||||
} finally { |
||||
response.close(); |
||||
} |
||||
logger.info("Ding Talk send [{}], resp:{%s}", msg); |
||||
return resp; |
||||
} finally { |
||||
httpClient.close(); |
||||
} |
||||
} |
||||
|
||||
public static HttpPost constructHttpPost(String msg, String charset) { |
||||
HttpPost post = new HttpPost(DING_TASK_URL); |
||||
StringEntity entity = new StringEntity(msg, charset); |
||||
post.setEntity(entity); |
||||
post.addHeader("Content-Type", "application/json; charset=utf-8"); |
||||
return post; |
||||
} |
||||
|
||||
public static CloseableHttpClient getProxyClient() { |
||||
HttpHost httpProxy = new HttpHost(PROXY, PORT); |
||||
CredentialsProvider provider = new BasicCredentialsProvider(); |
||||
provider.setCredentials(new AuthScope(httpProxy), new UsernamePasswordCredentials(USER, PASSWD)); |
||||
return HttpClients.custom().setDefaultCredentialsProvider(provider).build(); |
||||
} |
||||
|
||||
public static CloseableHttpClient getDefaultClient() { |
||||
return HttpClients.createDefault(); |
||||
} |
||||
|
||||
public static RequestConfig getProxyConfig() { |
||||
HttpHost httpProxy = new HttpHost(PROXY, PORT); |
||||
return RequestConfig.custom().setProxy(httpProxy).build(); |
||||
} |
||||
|
||||
public static String textToJsonString(String text) { |
||||
Map<String, Object> items = new HashMap<>(); |
||||
items.put("msgtype", "text"); |
||||
Map<String, String> textContent = new HashMap<>(); |
||||
byte[] byt = StringUtils.getBytesUtf8(text); |
||||
String txt = StringUtils.newStringUtf8(byt); |
||||
textContent.put("content", txt); |
||||
items.put("text", textContent); |
||||
|
||||
return JSONUtils.toJsonString(items); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,286 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.utils; |
||||
|
||||
import org.apache.dolphinscheduler.common.enums.ShowType; |
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils; |
||||
import org.apache.dolphinscheduler.common.utils.StringUtils; |
||||
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; |
||||
import org.apache.http.client.methods.HttpPost; |
||||
import org.apache.http.entity.StringEntity; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.apache.http.impl.client.HttpClients; |
||||
import org.apache.http.util.EntityUtils; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Collection; |
||||
import java.util.Iterator; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* Enterprise WeChat utils |
||||
*/ |
||||
public class EnterpriseWeChatUtils { |
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(EnterpriseWeChatUtils.class); |
||||
public static final String ENTERPRISE_WE_CHAT_AGENT_ID = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_AGENT_ID); |
||||
public static final String ENTERPRISE_WE_CHAT_USERS = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USERS); |
||||
private static final String ENTERPRISE_WE_CHAT_CORP_ID = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_CORP_ID); |
||||
private static final String ENTERPRISE_WE_CHAT_SECRET = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_SECRET); |
||||
private static final String ENTERPRISE_WE_CHAT_TOKEN_URL = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_TOKEN_URL); |
||||
private static final String ENTERPRISE_WE_CHAT_TOKEN_URL_REPLACE = ENTERPRISE_WE_CHAT_TOKEN_URL == null ? null : ENTERPRISE_WE_CHAT_TOKEN_URL |
||||
.replaceAll("\\{corpId}", ENTERPRISE_WE_CHAT_CORP_ID) |
||||
.replaceAll("\\{secret}", ENTERPRISE_WE_CHAT_SECRET); |
||||
private static final String ENTERPRISE_WE_CHAT_PUSH_URL = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_PUSH_URL); |
||||
private static final String ENTERPRISE_WE_CHAT_TEAM_SEND_MSG = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_TEAM_SEND_MSG); |
||||
private static final String ENTERPRISE_WE_CHAT_USER_SEND_MSG = PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USER_SEND_MSG); |
||||
|
||||
private static final String AGENT_ID_REG_EXP = "\\{agentId}"; |
||||
private static final String MSG_REG_EXP = "\\{msg}"; |
||||
private static final String USER_REG_EXP = "\\{toUser}"; |
||||
|
||||
private EnterpriseWeChatUtils() { |
||||
throw new IllegalStateException(EnterpriseWeChatUtils.class.getName()); |
||||
} |
||||
|
||||
/** |
||||
* get Enterprise WeChat is enable |
||||
* |
||||
* @return isEnable |
||||
*/ |
||||
public static boolean isEnable() { |
||||
Boolean isEnable = null; |
||||
try { |
||||
isEnable = PropertyUtils.getBoolean(Constants.ENTERPRISE_WECHAT_ENABLE); |
||||
} catch (Exception e) { |
||||
logger.error(e.getMessage(), e); |
||||
} |
||||
if (isEnable == null) { |
||||
return false; |
||||
} |
||||
return isEnable; |
||||
} |
||||
|
||||
/** |
||||
* get Enterprise WeChat token info |
||||
* |
||||
* @return token string info |
||||
* @throws IOException the IOException |
||||
*/ |
||||
public static String getToken() throws IOException { |
||||
String resp; |
||||
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault(); |
||||
try { |
||||
HttpGet httpGet = new HttpGet(ENTERPRISE_WE_CHAT_TOKEN_URL_REPLACE); |
||||
CloseableHttpResponse response = httpClient.execute(httpGet); |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
resp = EntityUtils.toString(entity, Constants.UTF_8); |
||||
EntityUtils.consume(entity); |
||||
} finally { |
||||
response.close(); |
||||
} |
||||
|
||||
Map<String, String> map = JSONUtils.toMap(resp); |
||||
return map == null ? null : map.get("access_token"); |
||||
} finally { |
||||
httpClient.close(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* make team single Enterprise WeChat message |
||||
* |
||||
* @param toParty the toParty |
||||
* @param agentId the agentId |
||||
* @param msg the msg |
||||
* @return Enterprise WeChat send message |
||||
*/ |
||||
public static String makeTeamSendMsg(String toParty, String agentId, String msg) { |
||||
return ENTERPRISE_WE_CHAT_TEAM_SEND_MSG.replaceAll("\\{toParty}", toParty) |
||||
.replaceAll(AGENT_ID_REG_EXP, agentId) |
||||
.replaceAll(MSG_REG_EXP, msg); |
||||
} |
||||
|
||||
/** |
||||
* make team multi Enterprise WeChat message |
||||
* |
||||
* @param toParty the toParty |
||||
* @param agentId the agentId |
||||
* @param msg the msg |
||||
* @return Enterprise WeChat send message |
||||
*/ |
||||
public static String makeTeamSendMsg(Collection<String> toParty, String agentId, String msg) { |
||||
String listParty = FuncUtils.mkString(toParty, "|"); |
||||
return ENTERPRISE_WE_CHAT_TEAM_SEND_MSG.replaceAll("\\{toParty}", listParty) |
||||
.replaceAll(AGENT_ID_REG_EXP, agentId) |
||||
.replaceAll(MSG_REG_EXP, msg); |
||||
} |
||||
|
||||
/** |
||||
* make team single user message |
||||
* |
||||
* @param toUser the toUser |
||||
* @param agentId the agentId |
||||
* @param msg the msg |
||||
* @return Enterprise WeChat send message |
||||
*/ |
||||
public static String makeUserSendMsg(String toUser, String agentId, String msg) { |
||||
return ENTERPRISE_WE_CHAT_USER_SEND_MSG.replaceAll(USER_REG_EXP, toUser) |
||||
.replaceAll(AGENT_ID_REG_EXP, agentId) |
||||
.replaceAll(MSG_REG_EXP, msg); |
||||
} |
||||
|
||||
/** |
||||
* make team multi user message |
||||
* |
||||
* @param toUser the toUser |
||||
* @param agentId the agentId |
||||
* @param msg the msg |
||||
* @return Enterprise WeChat send message |
||||
*/ |
||||
public static String makeUserSendMsg(Collection<String> toUser, String agentId, String msg) { |
||||
String listUser = FuncUtils.mkString(toUser, "|"); |
||||
return ENTERPRISE_WE_CHAT_USER_SEND_MSG.replaceAll(USER_REG_EXP, listUser) |
||||
.replaceAll(AGENT_ID_REG_EXP, agentId) |
||||
.replaceAll(MSG_REG_EXP, msg); |
||||
} |
||||
|
||||
/** |
||||
* send Enterprise WeChat |
||||
* |
||||
* @param charset the charset |
||||
* @param data the data |
||||
* @param token the token |
||||
* @return Enterprise WeChat resp, demo: {"errcode":0,"errmsg":"ok","invaliduser":""} |
||||
* @throws IOException the IOException |
||||
*/ |
||||
public static String sendEnterpriseWeChat(String charset, String data, String token) throws IOException { |
||||
String enterpriseWeChatPushUrlReplace = ENTERPRISE_WE_CHAT_PUSH_URL.replaceAll("\\{token}", token); |
||||
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault(); |
||||
try { |
||||
HttpPost httpPost = new HttpPost(enterpriseWeChatPushUrlReplace); |
||||
httpPost.setEntity(new StringEntity(data, charset)); |
||||
CloseableHttpResponse response = httpClient.execute(httpPost); |
||||
String resp; |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
resp = EntityUtils.toString(entity, charset); |
||||
EntityUtils.consume(entity); |
||||
} finally { |
||||
response.close(); |
||||
} |
||||
logger.info("Enterprise WeChat send [{}], param:{}, resp:{}", |
||||
ENTERPRISE_WE_CHAT_PUSH_URL, data, resp); |
||||
return resp; |
||||
} finally { |
||||
httpClient.close(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* convert table to markdown style |
||||
* |
||||
* @param title the title |
||||
* @param content the content |
||||
* @return markdown table content |
||||
*/ |
||||
public static String markdownTable(String title, String content) { |
||||
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class); |
||||
StringBuilder contents = new StringBuilder(200); |
||||
|
||||
if (null != mapItemsList) { |
||||
for (LinkedHashMap mapItems : mapItemsList) { |
||||
Set<Map.Entry<String, Object>> entries = mapItems.entrySet(); |
||||
Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); |
||||
StringBuilder t = new StringBuilder(String.format("`%s`%s", title, Constants.MARKDOWN_ENTER)); |
||||
|
||||
while (iterator.hasNext()) { |
||||
|
||||
Map.Entry<String, Object> entry = iterator.next(); |
||||
t.append(Constants.MARKDOWN_QUOTE); |
||||
t.append(entry.getKey()).append(":").append(entry.getValue()); |
||||
t.append(Constants.MARKDOWN_ENTER); |
||||
} |
||||
contents.append(t); |
||||
} |
||||
} |
||||
return contents.toString(); |
||||
} |
||||
|
||||
/** |
||||
* convert text to markdown style |
||||
* |
||||
* @param title the title |
||||
* @param content the content |
||||
* @return markdown text |
||||
*/ |
||||
public static String markdownText(String title, String content) { |
||||
if (StringUtils.isNotEmpty(content)) { |
||||
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class); |
||||
if (null != mapItemsList) { |
||||
StringBuilder contents = new StringBuilder(100); |
||||
contents.append(String.format("`%s`%n", title)); |
||||
for (LinkedHashMap mapItems : mapItemsList) { |
||||
|
||||
Set<Map.Entry<String, Object>> entries = mapItems.entrySet(); |
||||
Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); |
||||
while (iterator.hasNext()) { |
||||
Map.Entry<String, Object> entry = iterator.next(); |
||||
contents.append(Constants.MARKDOWN_QUOTE); |
||||
contents.append(entry.getKey()).append(":").append(entry.getValue()); |
||||
contents.append(Constants.MARKDOWN_ENTER); |
||||
} |
||||
|
||||
} |
||||
return contents.toString(); |
||||
} |
||||
|
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Determine the mardown style based on the show type of the alert |
||||
* |
||||
* @return the markdown alert table/text |
||||
*/ |
||||
public static String markdownByAlert(AlertData alert) { |
||||
String result = ""; |
||||
if (alert.getShowType().equals(ShowType.TABLE.getDescp())) { |
||||
result = markdownTable(alert.getTitle(), alert.getContent()); |
||||
} else if (alert.getShowType().equals(ShowType.TEXT.getDescp())) { |
||||
result = markdownText(alert.getTitle(), alert.getContent()); |
||||
} |
||||
return result; |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,375 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.utils; |
||||
|
||||
import org.apache.dolphinscheduler.alert.template.AlertTemplate; |
||||
import org.apache.dolphinscheduler.alert.template.AlertTemplateFactory; |
||||
import org.apache.dolphinscheduler.common.enums.ShowType; |
||||
import org.apache.dolphinscheduler.common.utils.CollectionUtils; |
||||
import org.apache.dolphinscheduler.common.utils.StringUtils; |
||||
|
||||
import org.apache.commons.mail.EmailException; |
||||
import org.apache.commons.mail.HtmlEmail; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.Collection; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Properties; |
||||
|
||||
import javax.mail.Authenticator; |
||||
import javax.mail.Message; |
||||
import javax.mail.MessagingException; |
||||
import javax.mail.PasswordAuthentication; |
||||
import javax.mail.Session; |
||||
import javax.mail.Transport; |
||||
import javax.mail.internet.InternetAddress; |
||||
import javax.mail.internet.MimeBodyPart; |
||||
import javax.mail.internet.MimeMessage; |
||||
import javax.mail.internet.MimeMultipart; |
||||
import javax.mail.internet.MimeUtility; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* mail utils |
||||
*/ |
||||
public class MailUtils { |
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(MailUtils.class); |
||||
|
||||
public static final String MAIL_PROTOCOL = PropertyUtils.getString(Constants.MAIL_PROTOCOL); |
||||
|
||||
public static final String MAIL_SERVER_HOST = PropertyUtils.getString(Constants.MAIL_SERVER_HOST); |
||||
|
||||
public static final Integer MAIL_SERVER_PORT = PropertyUtils.getInt(Constants.MAIL_SERVER_PORT); |
||||
|
||||
public static final String MAIL_SENDER = PropertyUtils.getString(Constants.MAIL_SENDER); |
||||
|
||||
public static final String MAIL_USER = PropertyUtils.getString(Constants.MAIL_USER); |
||||
|
||||
public static final String MAIL_PASSWD = PropertyUtils.getString(Constants.MAIL_PASSWD); |
||||
|
||||
public static final Boolean MAIL_USE_START_TLS = PropertyUtils.getBoolean(Constants.MAIL_SMTP_STARTTLS_ENABLE); |
||||
|
||||
public static final Boolean MAIL_USE_SSL = PropertyUtils.getBoolean(Constants.MAIL_SMTP_SSL_ENABLE); |
||||
|
||||
public static final String XLS_FILE_PATH = PropertyUtils.getString(Constants.XLS_FILE_PATH, "/tmp/xls"); |
||||
|
||||
public static final String STARTTLS_ENABLE = PropertyUtils.getString(Constants.MAIL_SMTP_STARTTLS_ENABLE); |
||||
|
||||
public static final Boolean SSL_ENABLE = PropertyUtils.getBoolean(Constants.MAIL_SMTP_SSL_ENABLE); |
||||
|
||||
public static final String SSL_TRUST = PropertyUtils.getString(Constants.MAIL_SMTP_SSL_TRUST); |
||||
|
||||
public static final AlertTemplate alertTemplate = AlertTemplateFactory.getMessageTemplate(); |
||||
|
||||
//Solve the problem of messy Chinese name in excel attachment
|
||||
static { |
||||
System.setProperty("mail.mime.splitlongparameters", "false"); |
||||
} |
||||
|
||||
private MailUtils() { |
||||
throw new IllegalStateException(MailUtils.class.getName()); |
||||
} |
||||
|
||||
/** |
||||
* send mail to receivers |
||||
* |
||||
* @param receivers the receiver list |
||||
* @param title the title |
||||
* @param content the content |
||||
* @param showType the show type |
||||
* @return the result map |
||||
*/ |
||||
public static Map<String, Object> sendMails(Collection<String> receivers, String title, String content, String showType) { |
||||
return sendMails(receivers, null, title, content, showType); |
||||
} |
||||
|
||||
/** |
||||
* send mail |
||||
* |
||||
* @param receivers the receiver list |
||||
* @param receiversCc cc list |
||||
* @param title the title |
||||
* @param content the content |
||||
* @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, String showType) { |
||||
Map<String, Object> retMap = new HashMap<>(); |
||||
retMap.put(Constants.STATUS, false); |
||||
|
||||
// if there is no receivers && no receiversCc, no need to process
|
||||
if (CollectionUtils.isEmpty(receivers) && CollectionUtils.isEmpty(receiversCc)) { |
||||
return retMap; |
||||
} |
||||
|
||||
receivers.removeIf(StringUtils::isEmpty); |
||||
|
||||
if (showType.equals(ShowType.TABLE.getDescp()) || showType.equals(ShowType.TEXT.getDescp())) { |
||||
// send email
|
||||
HtmlEmail email = new HtmlEmail(); |
||||
|
||||
try { |
||||
Session session = getSession(); |
||||
email.setMailSession(session); |
||||
email.setFrom(MAIL_SENDER); |
||||
email.setCharset(Constants.UTF_8); |
||||
if (CollectionUtils.isNotEmpty(receivers)) { |
||||
// receivers mail
|
||||
for (String receiver : receivers) { |
||||
email.addTo(receiver); |
||||
} |
||||
} |
||||
|
||||
if (CollectionUtils.isNotEmpty(receiversCc)) { |
||||
//cc
|
||||
for (String receiverCc : receiversCc) { |
||||
email.addCc(receiverCc); |
||||
} |
||||
} |
||||
// sender mail
|
||||
return getStringObjectMap(title, content, showType, retMap, email); |
||||
} catch (Exception e) { |
||||
handleException(receivers, retMap, e); |
||||
} |
||||
} else if (showType.equals(ShowType.ATTACHMENT.getDescp()) || showType.equals(ShowType.TABLEATTACHMENT.getDescp())) { |
||||
try { |
||||
|
||||
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); |
||||
|
||||
retMap.put(Constants.STATUS, true); |
||||
return retMap; |
||||
} catch (Exception e) { |
||||
handleException(receivers, retMap, e); |
||||
return retMap; |
||||
} |
||||
} |
||||
return retMap; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* html table content |
||||
* |
||||
* @param content the content |
||||
* @param showAll if show the whole content |
||||
* @return the html table form |
||||
*/ |
||||
private static String htmlTable(String content, boolean showAll) { |
||||
return alertTemplate.getMessageFromTemplate(content, ShowType.TABLE, showAll); |
||||
} |
||||
|
||||
/** |
||||
* html table content |
||||
* |
||||
* @param content the content |
||||
* @return the html table form |
||||
*/ |
||||
private static String htmlTable(String content) { |
||||
return htmlTable(content, true); |
||||
} |
||||
|
||||
/** |
||||
* html text content |
||||
* |
||||
* @param content the content |
||||
* @return text in html form |
||||
*/ |
||||
private static String htmlText(String content) { |
||||
return alertTemplate.getMessageFromTemplate(content, ShowType.TEXT); |
||||
} |
||||
|
||||
/** |
||||
* send mail as Excel attachment |
||||
* |
||||
* @param receivers the receiver list |
||||
* @param title the title |
||||
*/ |
||||
private static void attachment(Collection<String> receivers, Collection<String> receiversCc, String title, String content, String partContent) throws Exception { |
||||
MimeMessage msg = getMimeMessage(receivers); |
||||
|
||||
attachContent(receiversCc, title, content, partContent, msg); |
||||
} |
||||
|
||||
/** |
||||
* get MimeMessage |
||||
* |
||||
* @param receivers receivers |
||||
* @return the MimeMessage |
||||
*/ |
||||
private static MimeMessage getMimeMessage(Collection<String> receivers) throws MessagingException { |
||||
|
||||
// 1. The first step in creating mail: creating session
|
||||
Session session = getSession(); |
||||
// Setting debug mode, can be turned off
|
||||
session.setDebug(false); |
||||
|
||||
// 2. creating mail: Creating a MimeMessage
|
||||
MimeMessage msg = new MimeMessage(session); |
||||
// 3. set sender
|
||||
msg.setFrom(new InternetAddress(MAIL_SENDER)); |
||||
// 4. set receivers
|
||||
for (String receiver : receivers) { |
||||
msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver)); |
||||
} |
||||
return msg; |
||||
} |
||||
|
||||
/** |
||||
* get session |
||||
* |
||||
* @return the new Session |
||||
*/ |
||||
private static Session getSession() { |
||||
Properties props = new Properties(); |
||||
props.setProperty(Constants.MAIL_HOST, MAIL_SERVER_HOST); |
||||
props.setProperty(Constants.MAIL_PORT, String.valueOf(MAIL_SERVER_PORT)); |
||||
props.setProperty(Constants.MAIL_SMTP_AUTH, Constants.STRING_TRUE); |
||||
props.setProperty(Constants.MAIL_TRANSPORT_PROTOCOL, MAIL_PROTOCOL); |
||||
props.setProperty(Constants.MAIL_SMTP_STARTTLS_ENABLE, STARTTLS_ENABLE); |
||||
if (Boolean.TRUE.equals(SSL_ENABLE)) { |
||||
props.setProperty(Constants.MAIL_SMTP_SSL_ENABLE, "true"); |
||||
props.setProperty(Constants.MAIL_SMTP_SSL_TRUST, SSL_TRUST); |
||||
} |
||||
|
||||
Authenticator auth = new Authenticator() { |
||||
@Override |
||||
protected PasswordAuthentication getPasswordAuthentication() { |
||||
// mail username and password
|
||||
return new PasswordAuthentication(MAIL_USER, MAIL_PASSWD); |
||||
} |
||||
}; |
||||
|
||||
return Session.getInstance(props, auth); |
||||
} |
||||
|
||||
/** |
||||
* attach content |
||||
* |
||||
* @param receiversCc the cc list |
||||
* @param title the title |
||||
* @param content the content |
||||
* @param partContent the partContent |
||||
* @param msg the message |
||||
*/ |
||||
private static void attachContent(Collection<String> receiversCc, String title, String content, String partContent, MimeMessage msg) throws MessagingException, IOException { |
||||
/* |
||||
* set receiverCc |
||||
*/ |
||||
if (CollectionUtils.isNotEmpty(receiversCc)) { |
||||
for (String receiverCc : receiversCc) { |
||||
msg.addRecipients(Message.RecipientType.CC, InternetAddress.parse(receiverCc)); |
||||
} |
||||
} |
||||
|
||||
// set subject
|
||||
msg.setSubject(title); |
||||
MimeMultipart partList = new MimeMultipart(); |
||||
// set signature
|
||||
MimeBodyPart part1 = new MimeBodyPart(); |
||||
part1.setContent(partContent, Constants.TEXT_HTML_CHARSET_UTF_8); |
||||
// set attach file
|
||||
MimeBodyPart part2 = new MimeBodyPart(); |
||||
File file = new File(XLS_FILE_PATH + Constants.SINGLE_SLASH + title + Constants.EXCEL_SUFFIX_XLS); |
||||
if (!file.getParentFile().exists()) { |
||||
file.getParentFile().mkdirs(); |
||||
} |
||||
// make excel file
|
||||
|
||||
ExcelUtils.genExcelFile(content, title, XLS_FILE_PATH); |
||||
|
||||
part2.attachFile(file); |
||||
part2.setFileName(MimeUtility.encodeText(title + Constants.EXCEL_SUFFIX_XLS, Constants.UTF_8, "B")); |
||||
// add components to collection
|
||||
partList.addBodyPart(part1); |
||||
partList.addBodyPart(part2); |
||||
msg.setContent(partList); |
||||
// 5. send Transport
|
||||
Transport.send(msg); |
||||
// 6. delete saved file
|
||||
deleteFile(file); |
||||
} |
||||
|
||||
/** |
||||
* the string object map |
||||
* |
||||
* @param title the title |
||||
* @param content the content |
||||
* @param showType the showType |
||||
* @param retMap the result map |
||||
* @param email the email |
||||
* @return the result map |
||||
*/ |
||||
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 |
||||
*/ |
||||
email.setSubject(title); |
||||
/* |
||||
* to send information, you can use HTML tags in mail content because of the use of HtmlEmail |
||||
*/ |
||||
if (showType.equals(ShowType.TABLE.getDescp())) { |
||||
email.setMsg(htmlTable(content)); |
||||
} else if (showType.equals(ShowType.TEXT.getDescp())) { |
||||
email.setMsg(htmlText(content)); |
||||
} |
||||
|
||||
// send
|
||||
email.send(); |
||||
|
||||
retMap.put(Constants.STATUS, true); |
||||
|
||||
return retMap; |
||||
} |
||||
|
||||
/** |
||||
* file delete |
||||
* |
||||
* @param file the file to delete |
||||
*/ |
||||
public static void deleteFile(File file) { |
||||
if (file.exists()) { |
||||
if (file.delete()) { |
||||
logger.info("delete success: {}", file.getAbsolutePath() + file.getName()); |
||||
} else { |
||||
logger.info("delete fail: {}", file.getAbsolutePath() + file.getName()); |
||||
} |
||||
} else { |
||||
logger.info("file not exists: {}", file.getAbsolutePath() + file.getName()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* handle exception |
||||
* |
||||
* @param receivers the receiver list |
||||
* @param retMap the result map |
||||
* @param e the exception |
||||
*/ |
||||
private static void handleException(Collection<String> receivers, Map<String, Object> retMap, Exception e) { |
||||
logger.error("Send email to {} failed", receivers, e); |
||||
retMap.put(Constants.MESSAGE, "Send email to {" + String.join(",", receivers) + "} failed," + e.toString()); |
||||
} |
||||
} |
@ -1,91 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert; |
||||
|
||||
import org.apache.dolphinscheduler.alert.plugin.AlertPluginManager; |
||||
import org.apache.dolphinscheduler.alert.plugin.DolphinPluginLoader; |
||||
import org.apache.dolphinscheduler.alert.plugin.DolphinPluginManagerConfig; |
||||
import org.apache.dolphinscheduler.alert.runner.AlertSender; |
||||
import org.apache.dolphinscheduler.alert.utils.Constants; |
||||
import org.apache.dolphinscheduler.dao.AlertDao; |
||||
import org.apache.dolphinscheduler.dao.DaoFactory; |
||||
import org.apache.dolphinscheduler.dao.PluginDao; |
||||
import org.apache.dolphinscheduler.remote.NettyRemotingServer; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
|
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.powermock.api.mockito.PowerMockito; |
||||
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||
import org.powermock.modules.junit4.PowerMockRunner; |
||||
|
||||
@RunWith(PowerMockRunner.class) |
||||
@PrepareForTest({AlertServer.class,DaoFactory.class}) |
||||
public class AlertServerTest { |
||||
|
||||
@Before |
||||
public void before() { |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testMain() throws Exception { |
||||
AlertDao alertDao = PowerMockito.mock(AlertDao.class); |
||||
PowerMockito.mockStatic(DaoFactory.class); |
||||
PowerMockito.when(DaoFactory.getDaoInstance(AlertDao.class)).thenReturn(alertDao); |
||||
|
||||
PluginDao pluginDao = PowerMockito.mock(PluginDao.class); |
||||
PowerMockito.when(DaoFactory.getDaoInstance(PluginDao.class)).thenReturn(pluginDao); |
||||
|
||||
AlertChannel alertChannelMock = PowerMockito.mock(AlertChannel.class); |
||||
|
||||
AlertPluginManager alertPluginManager = PowerMockito.mock(AlertPluginManager.class); |
||||
PowerMockito.whenNew(AlertPluginManager.class).withNoArguments().thenReturn(alertPluginManager); |
||||
ConcurrentHashMap alertChannelMap = new ConcurrentHashMap<>(); |
||||
alertChannelMap.put("pluginName",alertChannelMock); |
||||
PowerMockito.when(alertPluginManager.getAlertChannelMap()).thenReturn(alertChannelMap); |
||||
|
||||
DolphinPluginManagerConfig alertPluginManagerConfig = PowerMockito.mock(DolphinPluginManagerConfig.class); |
||||
PowerMockito.whenNew(DolphinPluginManagerConfig.class).withNoArguments().thenReturn(alertPluginManagerConfig); |
||||
|
||||
NettyRemotingServer nettyRemotingServer = PowerMockito.mock(NettyRemotingServer.class); |
||||
PowerMockito.whenNew(NettyRemotingServer.class).withAnyArguments().thenReturn(nettyRemotingServer); |
||||
AlertSender alertSender = PowerMockito.mock(AlertSender.class); |
||||
PowerMockito.whenNew(AlertSender.class).withAnyArguments().thenReturn(alertSender); |
||||
|
||||
DolphinPluginLoader dolphinPluginLoader = PowerMockito.mock(DolphinPluginLoader.class); |
||||
PowerMockito.whenNew(DolphinPluginLoader.class).withAnyArguments().thenReturn(dolphinPluginLoader); |
||||
|
||||
AlertServer alertServer = AlertServer.getInstance(); |
||||
Assert.assertNotNull(alertServer); |
||||
|
||||
new Thread(() -> { |
||||
alertServer.start(); }) |
||||
.start(); |
||||
|
||||
Thread.sleep(5 * Constants.ALERT_SCAN_INTERVAL); |
||||
|
||||
alertServer.stop(); |
||||
|
||||
} |
||||
|
||||
} |
@ -1,65 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.plugin; |
||||
|
||||
import org.apache.dolphinscheduler.alert.AlertServer; |
||||
import org.apache.dolphinscheduler.alert.utils.Constants; |
||||
import org.apache.dolphinscheduler.alert.utils.PropertyUtils; |
||||
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Ignore; |
||||
import org.junit.Test; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
|
||||
/** |
||||
* AlertPluginManager Tester. |
||||
*/ |
||||
@Ignore |
||||
public class AlertPluginManagerTest { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AlertPluginManagerTest.class); |
||||
|
||||
@Test |
||||
public void testLoadPlugins() throws Exception { |
||||
logger.info("begin test AlertPluginManagerTest"); |
||||
AlertPluginManager alertPluginManager = new AlertPluginManager(); |
||||
DolphinPluginManagerConfig alertPluginManagerConfig = new DolphinPluginManagerConfig(); |
||||
String path = DolphinPluginLoader.class.getClassLoader().getResource("").getPath(); |
||||
alertPluginManagerConfig.setPlugins(path + "../../../dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/pom.xml"); |
||||
if (StringUtils.isNotBlank(PropertyUtils.getString(AlertServer.ALERT_PLUGIN_DIR))) { |
||||
alertPluginManagerConfig.setInstalledPluginsDir(org.apache.dolphinscheduler.alert.utils.PropertyUtils.getString(AlertServer.ALERT_PLUGIN_DIR, Constants.ALERT_PLUGIN_PATH).trim()); |
||||
} |
||||
|
||||
if (StringUtils.isNotBlank(PropertyUtils.getString(AlertServer.MAVEN_LOCAL_REPOSITORY))) { |
||||
alertPluginManagerConfig.setMavenLocalRepository(PropertyUtils.getString(AlertServer.MAVEN_LOCAL_REPOSITORY).trim()); |
||||
} |
||||
|
||||
DolphinPluginLoader alertPluginLoader = new DolphinPluginLoader(alertPluginManagerConfig, ImmutableList.of(alertPluginManager)); |
||||
try { |
||||
alertPluginLoader.loadPlugins(); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException("load Alert Plugin Failed !", e); |
||||
} |
||||
|
||||
Assert.assertNotNull(alertPluginManager.getAlertChannelFactoryMap().get("email alert")); |
||||
} |
||||
} |
@ -1,60 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.plugin; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Ignore; |
||||
import org.junit.Test; |
||||
|
||||
import com.google.common.collect.ImmutableList; |
||||
|
||||
/** |
||||
* DolphinPluginLoader Tester. |
||||
*/ |
||||
@Ignore |
||||
public class DolphinPluginLoaderTest { |
||||
|
||||
@Before |
||||
public void before() throws Exception { |
||||
} |
||||
|
||||
@After |
||||
public void after() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Method: loadPlugins() |
||||
*/ |
||||
@Test |
||||
public void testLoadPlugins() throws Exception { |
||||
AlertPluginManager alertPluginManager = new AlertPluginManager(); |
||||
DolphinPluginManagerConfig alertPluginManagerConfig = new DolphinPluginManagerConfig(); |
||||
String path = DolphinPluginLoader.class.getClassLoader().getResource("").getPath(); |
||||
alertPluginManagerConfig.setPlugins(path + "../../../dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/pom.xml"); |
||||
DolphinPluginLoader alertPluginLoader = new DolphinPluginLoader(alertPluginManagerConfig, ImmutableList.of(alertPluginManager)); |
||||
try { |
||||
alertPluginLoader.loadPlugins(); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException("load Alert Plugin Failed !", e); |
||||
} |
||||
|
||||
Assert.assertNotNull(alertPluginManager.getAlertChannelFactoryMap().get("email alert")); |
||||
} |
||||
} |
@ -1,61 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.processor; |
||||
|
||||
import org.apache.dolphinscheduler.alert.plugin.AlertPluginManager; |
||||
import org.apache.dolphinscheduler.dao.AlertDao; |
||||
import org.apache.dolphinscheduler.dao.PluginDao; |
||||
import org.apache.dolphinscheduler.remote.command.Command; |
||||
import org.apache.dolphinscheduler.remote.command.CommandType; |
||||
import org.apache.dolphinscheduler.remote.command.alert.AlertSendRequestCommand; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.powermock.api.mockito.PowerMockito; |
||||
|
||||
import io.netty.channel.Channel; |
||||
|
||||
/** |
||||
* alert request processor test |
||||
*/ |
||||
public class AlertRequestProcessorTest { |
||||
|
||||
private AlertDao alertDao; |
||||
private PluginDao pluginDao; |
||||
private AlertPluginManager alertPluginManager; |
||||
|
||||
private AlertRequestProcessor alertRequestProcessor; |
||||
|
||||
@Before |
||||
public void before() { |
||||
alertDao = PowerMockito.mock(AlertDao.class); |
||||
pluginDao = PowerMockito.mock(PluginDao.class); |
||||
alertPluginManager = PowerMockito.mock(AlertPluginManager.class); |
||||
alertRequestProcessor = new AlertRequestProcessor(alertDao,alertPluginManager,pluginDao); |
||||
} |
||||
|
||||
@Test |
||||
public void testProcess() { |
||||
Channel channel = PowerMockito.mock(Channel.class); |
||||
AlertSendRequestCommand alertSendRequestCommand = new AlertSendRequestCommand(1,"title","content"); |
||||
Command reqCommand = alertSendRequestCommand.convert2Command(); |
||||
Assert.assertEquals(CommandType.ALERT_SEND_REQUEST,reqCommand.getType()); |
||||
alertRequestProcessor.process(channel,reqCommand); |
||||
} |
||||
} |
@ -1,181 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.runner; |
||||
|
||||
import org.apache.dolphinscheduler.alert.plugin.AlertPluginManager; |
||||
import org.apache.dolphinscheduler.dao.AlertDao; |
||||
import org.apache.dolphinscheduler.dao.PluginDao; |
||||
import org.apache.dolphinscheduler.dao.entity.Alert; |
||||
import org.apache.dolphinscheduler.dao.entity.AlertPluginInstance; |
||||
import org.apache.dolphinscheduler.dao.entity.PluginDefine; |
||||
import org.apache.dolphinscheduler.remote.command.alert.AlertSendResponseCommand; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertChannel; |
||||
import org.apache.dolphinscheduler.spi.alert.AlertResult; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.mockito.Mockito; |
||||
import org.powermock.api.mockito.PowerMockito; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
/** |
||||
* alert sender test |
||||
*/ |
||||
public class AlertSenderTest { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AlertSenderTest.class); |
||||
|
||||
private AlertDao alertDao; |
||||
private PluginDao pluginDao; |
||||
private AlertPluginManager alertPluginManager; |
||||
|
||||
private AlertSender alertSender; |
||||
|
||||
@Before |
||||
public void before() { |
||||
alertDao = PowerMockito.mock(AlertDao.class); |
||||
pluginDao = PowerMockito.mock(PluginDao.class); |
||||
alertPluginManager = PowerMockito.mock(AlertPluginManager.class); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testSyncHandler() { |
||||
|
||||
int alertGroupId = 1; |
||||
String title = "alert mail test title"; |
||||
String content = "alert mail test content"; |
||||
alertSender = new AlertSender(alertDao,alertPluginManager,pluginDao); |
||||
|
||||
//1.alert instance does not exist
|
||||
PowerMockito.when(alertDao.listInstanceByAlertGroupId(alertGroupId)).thenReturn(null); |
||||
|
||||
AlertSendResponseCommand alertSendResponseCommand = alertSender.syncHandler(alertGroupId, title, content); |
||||
Assert.assertFalse(alertSendResponseCommand.getResStatus()); |
||||
alertSendResponseCommand.getResResults().forEach(result -> |
||||
logger.info("alert send response result, status:{}, message:{}",result.getStatus(),result.getMessage())); |
||||
|
||||
//2.alert plugin does not exist
|
||||
int pluginDefineId = 1; |
||||
String pluginInstanceParams = "alert-instance-mail-params"; |
||||
String pluginInstanceName = "alert-instance-mail"; |
||||
List<AlertPluginInstance> alertInstanceList = new ArrayList<>(); |
||||
AlertPluginInstance alertPluginInstance = new AlertPluginInstance( |
||||
pluginDefineId,pluginInstanceParams,pluginInstanceName); |
||||
alertInstanceList.add(alertPluginInstance); |
||||
PowerMockito.when(alertDao.listInstanceByAlertGroupId(1)).thenReturn(alertInstanceList); |
||||
|
||||
String pluginName = "alert-plugin-mail"; |
||||
PluginDefine pluginDefine = new PluginDefine(pluginName,"1",null); |
||||
PowerMockito.when(pluginDao.getPluginDefineById(pluginDefineId)).thenReturn(pluginDefine); |
||||
|
||||
alertSendResponseCommand = alertSender.syncHandler(alertGroupId, title, content); |
||||
Assert.assertFalse(alertSendResponseCommand.getResStatus()); |
||||
alertSendResponseCommand.getResResults().forEach(result -> |
||||
logger.info("alert send response result, status:{}, message:{}",result.getStatus(),result.getMessage())); |
||||
|
||||
//3.alert result value is null
|
||||
AlertChannel alertChannelMock = PowerMockito.mock(AlertChannel.class); |
||||
PowerMockito.when(alertChannelMock.process(Mockito.any())).thenReturn(null); |
||||
Map<String, AlertChannel> alertChannelMap = new ConcurrentHashMap<>(); |
||||
alertChannelMap.put(pluginName,alertChannelMock); |
||||
PowerMockito.when(alertPluginManager.getAlertChannelMap()).thenReturn(alertChannelMap); |
||||
|
||||
alertSendResponseCommand = alertSender.syncHandler(alertGroupId, title, content); |
||||
Assert.assertFalse(alertSendResponseCommand.getResStatus()); |
||||
alertSendResponseCommand.getResResults().forEach(result -> |
||||
logger.info("alert send response result, status:{}, message:{}",result.getStatus(),result.getMessage())); |
||||
|
||||
//4.abnormal information inside the alert plug-in code
|
||||
AlertResult alertResult = new AlertResult(); |
||||
alertResult.setStatus(String.valueOf(false)); |
||||
alertResult.setMessage("Abnormal information inside the alert plug-in code"); |
||||
PowerMockito.when(alertChannelMock.process(Mockito.any())).thenReturn(alertResult); |
||||
alertChannelMap = new ConcurrentHashMap<>(); |
||||
alertChannelMap.put(pluginName,alertChannelMock); |
||||
PowerMockito.when(alertPluginManager.getAlertChannelMap()).thenReturn(alertChannelMap); |
||||
|
||||
alertSendResponseCommand = alertSender.syncHandler(alertGroupId, title, content); |
||||
Assert.assertFalse(alertSendResponseCommand.getResStatus()); |
||||
alertSendResponseCommand.getResResults().forEach(result -> |
||||
logger.info("alert send response result, status:{}, message:{}",result.getStatus(),result.getMessage())); |
||||
|
||||
//5.alert plugin send success
|
||||
alertResult = new AlertResult(); |
||||
alertResult.setStatus(String.valueOf(true)); |
||||
alertResult.setMessage(String.format("Alert Plugin %s send success",pluginInstanceName)); |
||||
PowerMockito.when(alertChannelMock.process(Mockito.any())).thenReturn(alertResult); |
||||
alertChannelMap = new ConcurrentHashMap<>(); |
||||
alertChannelMap.put(pluginName,alertChannelMock); |
||||
PowerMockito.when(alertPluginManager.getAlertChannelMap()).thenReturn(alertChannelMap); |
||||
|
||||
alertSendResponseCommand = alertSender.syncHandler(alertGroupId, title, content); |
||||
Assert.assertTrue(alertSendResponseCommand.getResStatus()); |
||||
alertSendResponseCommand.getResResults().forEach(result -> |
||||
logger.info("alert send response result, status:{}, message:{}",result.getStatus(),result.getMessage())); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testRun() { |
||||
int alertGroupId = 1; |
||||
String title = "alert mail test title"; |
||||
String content = "alert mail test content"; |
||||
List<Alert> alertList = new ArrayList<>(); |
||||
Alert alert = new Alert(); |
||||
alert.setAlertGroupId(alertGroupId); |
||||
alert.setTitle(title); |
||||
alert.setContent(content); |
||||
alertList.add(alert); |
||||
|
||||
alertSender = new AlertSender(alertList,alertDao,alertPluginManager,pluginDao); |
||||
|
||||
int pluginDefineId = 1; |
||||
String pluginInstanceParams = "alert-instance-mail-params"; |
||||
String pluginInstanceName = "alert-instance-mail"; |
||||
List<AlertPluginInstance> alertInstanceList = new ArrayList<>(); |
||||
AlertPluginInstance alertPluginInstance = new AlertPluginInstance( |
||||
pluginDefineId,pluginInstanceParams,pluginInstanceName); |
||||
alertInstanceList.add(alertPluginInstance); |
||||
PowerMockito.when(alertDao.listInstanceByAlertGroupId(alertGroupId)).thenReturn(alertInstanceList); |
||||
|
||||
String pluginName = "alert-plugin-mail"; |
||||
PluginDefine pluginDefine = new PluginDefine(pluginName,"1",null); |
||||
PowerMockito.when(pluginDao.getPluginDefineById(pluginDefineId)).thenReturn(pluginDefine); |
||||
|
||||
AlertResult alertResult = new AlertResult(); |
||||
alertResult.setStatus(String.valueOf(true)); |
||||
alertResult.setMessage(String.format("Alert Plugin %s send success",pluginInstanceName)); |
||||
AlertChannel alertChannelMock = PowerMockito.mock(AlertChannel.class); |
||||
PowerMockito.when(alertChannelMock.process(Mockito.any())).thenReturn(alertResult); |
||||
ConcurrentHashMap alertChannelMap = new ConcurrentHashMap<>(); |
||||
alertChannelMap.put(pluginName,alertChannelMock); |
||||
PowerMockito.when(alertPluginManager.getAlertChannelMap()).thenReturn(alertChannelMap); |
||||
Assert.assertTrue(Boolean.parseBoolean(alertResult.getStatus())); |
||||
alertSender.run(); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,65 @@
|
||||
/* |
||||
* 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.template; |
||||
|
||||
import org.apache.dolphinscheduler.alert.template.impl.DefaultHTMLTemplate; |
||||
import org.apache.dolphinscheduler.alert.utils.Constants; |
||||
import org.apache.dolphinscheduler.alert.utils.PropertyUtils; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Mockito; |
||||
import org.powermock.api.mockito.PowerMockito; |
||||
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||
import org.powermock.modules.junit4.PowerMockRunner; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import static org.mockito.Mockito.*; |
||||
import static org.junit.Assert.*; |
||||
|
||||
/** |
||||
* test class for AlertTemplateFactory |
||||
*/ |
||||
@RunWith(PowerMockRunner.class) |
||||
@PrepareForTest(PropertyUtils.class) |
||||
public class AlertTemplateFactoryTest { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AlertTemplateFactoryTest.class); |
||||
|
||||
/** |
||||
* GetMessageTemplate method test |
||||
*/ |
||||
@Test |
||||
public void testGetMessageTemplate(){ |
||||
|
||||
PowerMockito.mockStatic(PropertyUtils.class); |
||||
|
||||
AlertTemplate defaultTemplate = AlertTemplateFactory.getMessageTemplate(); |
||||
|
||||
assertTrue(defaultTemplate instanceof DefaultHTMLTemplate); |
||||
} |
||||
|
||||
/** |
||||
* GetMessageTemplate method throw Exception test |
||||
*/ |
||||
@Test |
||||
public void testGetMessageTemplateException(){ |
||||
|
||||
AlertTemplate defaultTemplate = AlertTemplateFactory.getMessageTemplate(); |
||||
assertTrue(defaultTemplate instanceof DefaultHTMLTemplate); |
||||
} |
||||
} |
@ -0,0 +1,96 @@
|
||||
/* |
||||
* 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.template.impl; |
||||
|
||||
import org.apache.dolphinscheduler.common.utils.*; |
||||
import org.apache.dolphinscheduler.alert.utils.Constants; |
||||
import org.apache.dolphinscheduler.common.enums.ShowType; |
||||
import org.junit.Test; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
|
||||
import static org.junit.Assert.*; |
||||
|
||||
/** |
||||
* test class for DefaultHTMLTemplate |
||||
*/ |
||||
public class DefaultHTMLTemplateTest{ |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultHTMLTemplateTest.class); |
||||
|
||||
/** |
||||
* only need test method GetMessageFromTemplate |
||||
*/ |
||||
@Test |
||||
public void testGetMessageFromTemplate(){ |
||||
|
||||
DefaultHTMLTemplate template = new DefaultHTMLTemplate(); |
||||
|
||||
String tableTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TABLE,true); |
||||
|
||||
assertEquals(tableTypeMessage,generateMockTableTypeResultByHand()); |
||||
|
||||
String textTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TEXT,true); |
||||
|
||||
assertEquals(textTypeMessage,generateMockTextTypeResultByHand()); |
||||
} |
||||
|
||||
/** |
||||
* generate some simulation data |
||||
*/ |
||||
private String list2String(){ |
||||
|
||||
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>(); |
||||
map1.put("mysql service name","mysql200"); |
||||
map1.put("mysql address","192.168.xx.xx"); |
||||
map1.put("database client connections","190"); |
||||
map1.put("port","3306"); |
||||
map1.put("no index of number","80"); |
||||
|
||||
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>(); |
||||
map2.put("mysql service name","mysql210"); |
||||
map2.put("mysql address","192.168.xx.xx"); |
||||
map2.put("database client connections","90"); |
||||
map2.put("port","3306"); |
||||
map2.put("no index of number","10"); |
||||
|
||||
List<LinkedHashMap<String, Object>> maps = new ArrayList<>(); |
||||
maps.add(0,map1); |
||||
maps.add(1,map2); |
||||
String mapjson = JSONUtils.toJsonString(maps); |
||||
logger.info(mapjson); |
||||
|
||||
return mapjson; |
||||
} |
||||
|
||||
private String generateMockTableTypeResultByHand(){ |
||||
|
||||
return Constants.HTML_HEADER_PREFIX + |
||||
"<thead><tr><th>mysql service name</th><th>mysql address</th><th>database client connections</th><th>port</th><th>no index of number</th></tr></thead>\n" + |
||||
"<tr><td>mysql200</td><td>192.168.xx.xx</td><td>190</td><td>3306</td><td>80</td></tr><tr><td>mysql210</td><td>192.168.xx.xx</td><td>90</td><td>3306</td><td>10</td></tr>" + Constants.TABLE_BODY_HTML_TAIL; |
||||
|
||||
} |
||||
|
||||
private String generateMockTextTypeResultByHand(){ |
||||
|
||||
return Constants.HTML_HEADER_PREFIX + "<tr><td>{\"mysql service name\":\"mysql200\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"190\",\"port\":\"3306\",\"no index of number\":\"80\"}</td></tr><tr><td>{\"mysql service name\":\"mysql210\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"90\",\"port\":\"3306\",\"no index of number\":\"10\"}</td></tr>" + Constants.TABLE_BODY_HTML_TAIL; |
||||
} |
||||
} |
@ -0,0 +1,120 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.apache.dolphinscheduler.alert.utils; |
||||
|
||||
import org.apache.http.client.config.RequestConfig; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Mockito; |
||||
import org.powermock.api.mockito.PowerMockito; |
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore; |
||||
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||
import org.powermock.modules.junit4.PowerMockRunner; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
@PrepareForTest(PropertyUtils.class) |
||||
@RunWith(PowerMockRunner.class) |
||||
@PowerMockIgnore("javax.net.ssl.*") |
||||
public class DingTalkUtilsTest { |
||||
Logger logger = LoggerFactory.getLogger(DingTalkUtilsTest.class); |
||||
|
||||
private static final String mockUrl = "https://oapi.dingtalk.com/robot/send?access_token=test"; |
||||
private static final String mockKeyWords = "onway"; |
||||
private static final String msg = "ding talk test"; |
||||
|
||||
@Before |
||||
public void init(){ |
||||
PowerMockito.mockStatic(PropertyUtils.class); |
||||
Mockito.when(PropertyUtils.getString(Constants.DINGTALK_WEBHOOK)).thenReturn(mockUrl); |
||||
Mockito.when(PropertyUtils.getString(Constants.DINGTALK_KEYWORD)).thenReturn(mockKeyWords); |
||||
Mockito.when(PropertyUtils.getBoolean(Constants.DINGTALK_PROXY_ENABLE)).thenReturn(true); |
||||
Mockito.when(PropertyUtils.getString(Constants.DINGTALK_PROXY)).thenReturn("proxy.com.cn"); |
||||
Mockito.when(PropertyUtils.getString(Constants.DINGTALK_USER)).thenReturn("user"); |
||||
Mockito.when(PropertyUtils.getString(Constants.DINGTALK_PASSWORD)).thenReturn("pswd"); |
||||
Mockito.when(PropertyUtils.getInt(Constants.DINGTALK_PORT)).thenReturn(80); |
||||
} |
||||
|
||||
// @Test
|
||||
// @Ignore
|
||||
// public void testSendMsg() {
|
||||
// try {
|
||||
// String msgTosend = "msg to send";
|
||||
// logger.info(PropertyUtils.getString(Constants.DINGTALK_WEBHOOK));
|
||||
// String rsp = DingTalkUtils.sendDingTalkMsg(msgTosend, Constants.UTF_8);
|
||||
// logger.info("send msg result:{}",rsp);
|
||||
// String errmsg = JSONUtils.parseObject(rsp).getString("errmsg");
|
||||
// Assert.assertEquals("ok", errmsg);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
@Test |
||||
public void testCreateDefaultClient() { |
||||
CloseableHttpClient client = DingTalkUtils.getDefaultClient();; |
||||
try { |
||||
Assert.assertNotNull(client); |
||||
client.close(); |
||||
} catch (IOException ex) { |
||||
logger.info("close exception",ex.getMessage()); |
||||
new Throwable(); |
||||
} |
||||
} |
||||
@Test |
||||
public void testCreateProxyClient() { |
||||
CloseableHttpClient client = DingTalkUtils.getProxyClient(); |
||||
try { |
||||
Assert.assertNotNull(client); |
||||
client.close(); |
||||
} catch (IOException ex) { |
||||
logger.info("close exception",ex.getMessage()); |
||||
new Throwable(); |
||||
} |
||||
|
||||
} |
||||
@Test |
||||
public void testProxyConfig() { |
||||
RequestConfig rc = DingTalkUtils.getProxyConfig(); |
||||
Assert.assertEquals(80, rc.getProxy().getPort()); |
||||
Assert.assertEquals("proxy.com.cn", rc.getProxy().getHostName()); |
||||
} |
||||
|
||||
@Test |
||||
public void testDingTalkMsgToJson() { |
||||
String jsonString = DingTalkUtils.textToJsonString("this is test"); |
||||
|
||||
logger.info(jsonString); |
||||
String expect = "{\"text\":{\"content\":\"this is test\"},\"msgtype\":\"text\"}"; |
||||
Assert.assertEquals(expect, jsonString); |
||||
} |
||||
@Test |
||||
public void testDingTalkMsgUtf8() { |
||||
String msg = DingTalkUtils.textToJsonString("this is test:中文"); |
||||
|
||||
logger.info("test support utf8, actual:" + msg); |
||||
logger.info("test support utf8, actual:" + DingTalkUtils.IS_ENABLE_DING_TALK); |
||||
String expect = "{\"text\":{\"content\":\"this is test:中文\"},\"msgtype\":\"text\"}"; |
||||
Assert.assertEquals(expect, msg); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,283 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.alert.utils; |
||||
|
||||
import org.apache.dolphinscheduler.common.enums.AlertType; |
||||
import org.apache.dolphinscheduler.common.enums.ShowType; |
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils; |
||||
import org.apache.dolphinscheduler.dao.entity.Alert; |
||||
import org.apache.dolphinscheduler.plugin.model.AlertData; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Mockito; |
||||
import org.powermock.api.mockito.PowerMockito; |
||||
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||
import org.powermock.modules.junit4.PowerMockRunner; |
||||
|
||||
/** |
||||
* Please manually modify the configuration file before testing. |
||||
* file: alert.properties |
||||
* enterprise.wechat.corp.id |
||||
* enterprise.wechat.secret |
||||
* enterprise.wechat.token.url |
||||
* enterprise.wechat.push.url |
||||
* enterprise.wechat.send.msg |
||||
* enterprise.wechat.agent.id |
||||
* enterprise.wechat.users |
||||
*/ |
||||
@PrepareForTest(PropertyUtils.class) |
||||
@RunWith(PowerMockRunner.class) |
||||
public class EnterpriseWeChatUtilsTest { |
||||
|
||||
private static final String toParty = "wwc99134b6fc1edb6"; |
||||
private static final String enterpriseWechatSecret = "Uuv2KFrkdf7SeKOsTDCpsTkpawXBMNRhFy6VKX5FV"; |
||||
private static final String enterpriseWechatAgentId = "1000004"; |
||||
private static final String enterpriseWechatUsers = "LiGang,journey"; |
||||
private static final String msg = "hello world"; |
||||
|
||||
private static final String enterpriseWechatTeamSendMsg = "{\\\"toparty\\\":\\\"{toParty}\\\",\\\"agentid\\\":\\\"{agentId}\\\"" |
||||
+ |
||||
",\\\"msgtype\\\":\\\"text\\\",\\\"text\\\":{\\\"content\\\":\\\"{msg}\\\"},\\\"safe\\\":\\\"0\\\"}"; |
||||
private static final String enterpriseWechatUserSendMsg = "{\\\"touser\\\":\\\"{toUser}\\\",\\\"agentid\\\":\\\"{agentId}\\\"" |
||||
+ |
||||
",\\\"msgtype\\\":\\\"markdown\\\",\\\"markdown\\\":{\\\"content\\\":\\\"{msg}\\\"}}"; |
||||
|
||||
@Before |
||||
public void init() { |
||||
PowerMockito.mockStatic(PropertyUtils.class); |
||||
Mockito.when(PropertyUtils.getBoolean(Constants.ENTERPRISE_WECHAT_ENABLE)).thenReturn(true); |
||||
Mockito.when(PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_USER_SEND_MSG)).thenReturn(enterpriseWechatUserSendMsg); |
||||
Mockito.when(PropertyUtils.getString(Constants.ENTERPRISE_WECHAT_TEAM_SEND_MSG)).thenReturn(enterpriseWechatTeamSendMsg); |
||||
} |
||||
|
||||
@Test |
||||
public void testIsEnable() { |
||||
Boolean weChartEnable = EnterpriseWeChatUtils.isEnable(); |
||||
Assert.assertTrue(weChartEnable); |
||||
} |
||||
|
||||
@Test |
||||
public void testMakeTeamSendMsg1() { |
||||
String sendMsg = EnterpriseWeChatUtils.makeTeamSendMsg(toParty, enterpriseWechatSecret, msg); |
||||
Assert.assertTrue(sendMsg.contains(toParty)); |
||||
Assert.assertTrue(sendMsg.contains(enterpriseWechatSecret)); |
||||
Assert.assertTrue(sendMsg.contains(msg)); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testMakeTeamSendMsg2() { |
||||
List<String> parties = new ArrayList<>(); |
||||
parties.add(toParty); |
||||
parties.add("test1"); |
||||
|
||||
String sendMsg = EnterpriseWeChatUtils.makeTeamSendMsg(parties, enterpriseWechatSecret, msg); |
||||
Assert.assertTrue(sendMsg.contains(toParty)); |
||||
Assert.assertTrue(sendMsg.contains(enterpriseWechatSecret)); |
||||
Assert.assertTrue(sendMsg.contains(msg)); |
||||
} |
||||
|
||||
@Test |
||||
public void tesMakeUserSendMsg1() { |
||||
|
||||
String sendMsg = EnterpriseWeChatUtils.makeUserSendMsg(enterpriseWechatUsers, enterpriseWechatAgentId, msg); |
||||
Assert.assertTrue(sendMsg.contains(enterpriseWechatUsers)); |
||||
Assert.assertTrue(sendMsg.contains(enterpriseWechatAgentId)); |
||||
Assert.assertTrue(sendMsg.contains(msg)); |
||||
} |
||||
|
||||
@Test |
||||
public void tesMakeUserSendMsg2() { |
||||
List<String> users = new ArrayList<>(); |
||||
users.add("user1"); |
||||
users.add("user2"); |
||||
|
||||
String sendMsg = EnterpriseWeChatUtils.makeUserSendMsg(users, enterpriseWechatAgentId, msg); |
||||
Assert.assertTrue(sendMsg.contains(users.get(0))); |
||||
Assert.assertTrue(sendMsg.contains(users.get(1))); |
||||
Assert.assertTrue(sendMsg.contains(enterpriseWechatAgentId)); |
||||
Assert.assertTrue(sendMsg.contains(msg)); |
||||
} |
||||
|
||||
@Test |
||||
public void testMarkdownByAlertForText() { |
||||
Alert alertForText = createAlertForText(); |
||||
AlertData alertData = new AlertData(); |
||||
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(); |
||||
AlertData alertData = new AlertData(); |
||||
alertData.setTitle(alertForText.getTitle()) |
||||
.setShowType(alertForText.getShowType().getDescp()) |
||||
.setContent(alertForText.getContent()); |
||||
String result = EnterpriseWeChatUtils.markdownByAlert(alertData); |
||||
Assert.assertNotNull(result); |
||||
} |
||||
|
||||
private Alert createAlertForText() { |
||||
String content = "[{\"id\":\"69\"," |
||||
+ |
||||
"\"name\":\"UserBehavior-0--1193959466\"," |
||||
+ |
||||
"\"Job name\":\"Start workflow\"," |
||||
+ |
||||
"\"State\":\"SUCCESS\"," |
||||
+ |
||||
"\"Recovery\":\"NO\"," |
||||
+ |
||||
"\"Run time\":\"1\"," |
||||
+ |
||||
"\"Start time\": \"2018-08-06 10:31:34.0\"," |
||||
+ |
||||
"\"End time\": \"2018-08-06 10:31:49.0\"," |
||||
+ |
||||
"\"Host\": \"192.168.xx.xx\"," |
||||
+ |
||||
"\"Notify group\" :\"4\"}]"; |
||||
|
||||
Alert alert = new Alert(); |
||||
alert.setTitle("Mysql Exception"); |
||||
alert.setShowType(ShowType.TEXT); |
||||
alert.setContent(content); |
||||
alert.setAlertType(AlertType.EMAIL); |
||||
alert.setAlertGroupId(4); |
||||
|
||||
return alert; |
||||
} |
||||
|
||||
private String list2String() { |
||||
|
||||
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>(); |
||||
map1.put("mysql service name", "mysql200"); |
||||
map1.put("mysql address", "192.168.xx.xx"); |
||||
map1.put("port", "3306"); |
||||
map1.put("no index of number", "80"); |
||||
map1.put("database client connections", "190"); |
||||
|
||||
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>(); |
||||
map2.put("mysql service name", "mysql210"); |
||||
map2.put("mysql address", "192.168.xx.xx"); |
||||
map2.put("port", "3306"); |
||||
map2.put("no index of number", "10"); |
||||
map2.put("database client connections", "90"); |
||||
|
||||
List<LinkedHashMap<String, Object>> maps = new ArrayList<>(); |
||||
maps.add(0, map1); |
||||
maps.add(1, map2); |
||||
String mapjson = JSONUtils.toJsonString(maps); |
||||
return mapjson; |
||||
} |
||||
|
||||
private Alert createAlertForTable() { |
||||
Alert alert = new Alert(); |
||||
alert.setTitle("Mysql Exception"); |
||||
alert.setShowType(ShowType.TABLE); |
||||
String content = list2String(); |
||||
alert.setContent(content); |
||||
alert.setAlertType(AlertType.EMAIL); |
||||
alert.setAlertGroupId(1); |
||||
return alert; |
||||
} |
||||
|
||||
|
||||
// @Test
|
||||
// public void testSendSingleTeamWeChat() {
|
||||
// try {
|
||||
// String token = EnterpriseWeChatUtils.getToken();
|
||||
// String msg = EnterpriseWeChatUtils.makeTeamSendMsg(partyId, agentId, "hello world");
|
||||
// String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token);
|
||||
//
|
||||
// String errmsg = JSONUtils.parseObject(resp).getString("errmsg");
|
||||
// Assert.assertEquals("ok",errmsg);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendMultiTeamWeChat() {
|
||||
//
|
||||
// try {
|
||||
// String token = EnterpriseWeChatUtils.getToken();
|
||||
// String msg = EnterpriseWeChatUtils.makeTeamSendMsg(listPartyId, agentId, "hello world");
|
||||
// String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token);
|
||||
//
|
||||
// String errmsg = JSONUtils.parseObject(resp).getString("errmsg");
|
||||
// Assert.assertEquals("ok",errmsg);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendSingleUserWeChat() {
|
||||
// try {
|
||||
// String token = EnterpriseWeChatUtils.getToken();
|
||||
// String msg = EnterpriseWeChatUtils.makeUserSendMsg(listUserId.stream().findFirst().get(), agentId, "your meeting room has been booked and will be synced to the 'mailbox' later \n" +
|
||||
// ">**matter details** \n" +
|
||||
// ">matter:<font color='info'>meeting</font> <br>" +
|
||||
// ">organizer:@miglioguan \n" +
|
||||
// ">participant:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang \n" +
|
||||
// "> \n" +
|
||||
// ">meeting room:<font color='info'>Guangzhou TIT 1st Floor 301</font> \n" +
|
||||
// ">date:<font color='warning'>May 18, 2018</font> \n" +
|
||||
// ">time:<font color='comment'>9:00-11:00 am</font> \n" +
|
||||
// "> \n" +
|
||||
// ">please attend the meeting on time\n" +
|
||||
// "> \n" +
|
||||
// ">to modify the meeting information, please click: [Modify Meeting Information](https://work.weixin.qq.com)\"");
|
||||
//
|
||||
// String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token);
|
||||
//
|
||||
// String errmsg = JSONUtils.parseObject(resp).getString("errmsg");
|
||||
// Assert.assertEquals("ok",errmsg);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendMultiUserWeChat() {
|
||||
// try {
|
||||
// String token = EnterpriseWeChatUtils.getToken();
|
||||
//
|
||||
// String msg = EnterpriseWeChatUtils.makeUserSendMsg(listUserId, agentId, "hello world");
|
||||
// String resp = EnterpriseWeChatUtils.sendEnterpriseWeChat("utf-8", msg, token);
|
||||
//
|
||||
// String errmsg = JSONUtils.parseObject(resp).getString("errmsg");
|
||||
// Assert.assertEquals("ok",errmsg);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
} |
@ -0,0 +1,190 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.apache.dolphinscheduler.alert.utils; |
||||
|
||||
|
||||
import org.apache.dolphinscheduler.common.enums.AlertType; |
||||
import org.apache.dolphinscheduler.common.enums.ShowType; |
||||
import org.apache.dolphinscheduler.dao.AlertDao; |
||||
import org.apache.dolphinscheduler.dao.DaoFactory; |
||||
import org.apache.dolphinscheduler.dao.entity.Alert; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import java.util.*; |
||||
import org.apache.dolphinscheduler.common.utils.*; |
||||
|
||||
|
||||
/** |
||||
*/ |
||||
public class MailUtilsTest { |
||||
private static final Logger logger = LoggerFactory.getLogger(MailUtilsTest.class); |
||||
@Test |
||||
public void testSendMails() { |
||||
String[] receivers = new String[]{"347801120@qq.com"}; |
||||
String[] receiversCc = new String[]{"347801120@qq.com"}; |
||||
|
||||
String content ="[\"id:69\"," + |
||||
"\"name:UserBehavior-0--1193959466\"," + |
||||
"\"Job name: Start workflow\"," + |
||||
"\"State: SUCCESS\"," + |
||||
"\"Recovery:NO\"," + |
||||
"\"Run time: 1\"," + |
||||
"\"Start time: 2018-08-06 10:31:34.0\"," + |
||||
"\"End time: 2018-08-06 10:31:49.0\"," + |
||||
"\"Host: 192.168.xx.xx\"," + |
||||
"\"Notify group :4\"]"; |
||||
|
||||
Alert alert = new Alert(); |
||||
alert.setTitle("Mysql Exception"); |
||||
alert.setShowType(ShowType.TEXT); |
||||
alert.setContent(content); |
||||
alert.setAlertType(AlertType.EMAIL); |
||||
alert.setAlertGroupId(4); |
||||
|
||||
MailUtils.sendMails(Arrays.asList(receivers),Arrays.asList(receiversCc),alert.getTitle(),alert.getContent(), ShowType.TEXT.getDescp()); |
||||
} |
||||
|
||||
|
||||
@Test |
||||
public void testQuery(){ |
||||
AlertDao alertDao = DaoFactory.getDaoInstance(AlertDao.class); |
||||
List<Alert> alerts = alertDao.listWaitExecutionAlert(); |
||||
|
||||
String[] mails = new String[]{"xx@xx.com"}; |
||||
|
||||
for(Alert alert : alerts){ |
||||
MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE.getDescp()); |
||||
} |
||||
|
||||
} |
||||
|
||||
public String list2String(){ |
||||
|
||||
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>(); |
||||
map1.put("mysql service name","mysql200"); |
||||
map1.put("mysql address","192.168.xx.xx"); |
||||
map1.put("port","3306"); |
||||
map1.put("no index of number","80"); |
||||
map1.put("database client connections","190"); |
||||
|
||||
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>(); |
||||
map2.put("mysql service name","mysql210"); |
||||
map2.put("mysql address","192.168.xx.xx"); |
||||
map2.put("port","3306"); |
||||
map2.put("no index of number","10"); |
||||
map2.put("database client connections","90"); |
||||
|
||||
List<LinkedHashMap<String, Object>> maps = new ArrayList<>(); |
||||
maps.add(0,map1); |
||||
maps.add(1,map2); |
||||
String mapjson = JSONUtils.toJsonString(maps); |
||||
logger.info(mapjson); |
||||
|
||||
return mapjson; |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testSendTableMail(){ |
||||
String[] mails = new String[]{"347801120@qq.com"}; |
||||
Alert alert = new Alert(); |
||||
alert.setTitle("Mysql Exception"); |
||||
alert.setShowType(ShowType.TABLE); |
||||
String content= list2String(); |
||||
alert.setContent(content); |
||||
alert.setAlertType(AlertType.EMAIL); |
||||
alert.setAlertGroupId(1); |
||||
MailUtils.sendMails(Arrays.asList(mails),"gaojing", alert.getContent(), ShowType.TABLE.getDescp()); |
||||
} |
||||
|
||||
/** |
||||
* Used to test add alarm information, mail sent |
||||
* Text |
||||
*/ |
||||
@Test |
||||
public void addAlertText(){ |
||||
AlertDao alertDao = DaoFactory.getDaoInstance(AlertDao.class); |
||||
Alert alert = new Alert(); |
||||
alert.setTitle("Mysql Exception"); |
||||
alert.setShowType(ShowType.TEXT); |
||||
alert.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\"]"); |
||||
alert.setAlertType(AlertType.EMAIL); |
||||
alert.setAlertGroupId(1); |
||||
alertDao.addAlert(alert); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Used to test add alarm information, mail sent |
||||
* Table |
||||
*/ |
||||
@Test |
||||
public void testAddAlertTable(){ |
||||
logger.info("testAddAlertTable"); |
||||
AlertDao alertDao = DaoFactory.getDaoInstance(AlertDao.class); |
||||
Assert.assertNotNull(alertDao); |
||||
Alert alert = new Alert(); |
||||
alert.setTitle("Mysql Exception"); |
||||
alert.setShowType(ShowType.TABLE); |
||||
|
||||
String content = list2String(); |
||||
alert.setContent(content); |
||||
alert.setAlertType(AlertType.EMAIL); |
||||
alert.setAlertGroupId(1); |
||||
alertDao.addAlert(alert); |
||||
logger.info("" +alert); |
||||
} |
||||
|
||||
@Test |
||||
public void testAlertDao(){ |
||||
AlertDao alertDao = DaoFactory.getDaoInstance(AlertDao.class); |
||||
List<User> users = alertDao.listUserByAlertgroupId(3); |
||||
logger.info(users.toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void testAttachmentFile()throws Exception{ |
||||
String[] mails = new String[]{"xx@xx.com"}; |
||||
Alert alert = new Alert(); |
||||
alert.setTitle("Mysql Exception"); |
||||
alert.setShowType(ShowType.ATTACHMENT); |
||||
String content = list2String(); |
||||
alert.setContent(content); |
||||
alert.setAlertType(AlertType.EMAIL); |
||||
alert.setAlertGroupId(1); |
||||
MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.ATTACHMENT.getDescp()); |
||||
} |
||||
|
||||
@Test |
||||
public void testTableAttachmentFile()throws Exception{ |
||||
String[] mails = new String[]{"xx@xx.com"}; |
||||
Alert alert = new Alert(); |
||||
alert.setTitle("Mysql Exception"); |
||||
alert.setShowType(ShowType.TABLEATTACHMENT); |
||||
String content = list2String(); |
||||
alert.setContent(content); |
||||
alert.setAlertType(AlertType.EMAIL); |
||||
alert.setAlertGroupId(1); |
||||
MailUtils.sendMails(Arrays.asList(mails),"gaojing",alert.getContent(),ShowType.TABLEATTACHMENT.getDescp()); |
||||
} |
||||
|
||||
} |
@ -1,240 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.controller; |
||||
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.CREATE_ALERT_PLUGIN_INSTANCE_ERROR; |
||||
import static org.apache.dolphinscheduler.api.enums.Status.DELETE_ALERT_PLUGIN_INSTANCE_ERROR; |
||||
import static org.apache.dolphinscheduler.api.enums.Status.GET_ALERT_PLUGIN_INSTANCE_ERROR; |
||||
import static org.apache.dolphinscheduler.api.enums.Status.LIST_PAGING_ALERT_PLUGIN_INSTANCE_ERROR; |
||||
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_ALL_ALERT_PLUGIN_INSTANCE_ERROR; |
||||
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_ALERT_PLUGIN_INSTANCE_ERROR; |
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status; |
||||
import org.apache.dolphinscheduler.api.exceptions.ApiException; |
||||
import org.apache.dolphinscheduler.api.service.AlertPluginInstanceService; |
||||
import org.apache.dolphinscheduler.api.utils.Result; |
||||
import org.apache.dolphinscheduler.common.Constants; |
||||
import org.apache.dolphinscheduler.common.utils.StringUtils; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.http.HttpStatus; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestAttribute; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.springframework.web.bind.annotation.ResponseStatus; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import io.swagger.annotations.Api; |
||||
import io.swagger.annotations.ApiImplicitParam; |
||||
import io.swagger.annotations.ApiImplicitParams; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import springfox.documentation.annotations.ApiIgnore; |
||||
|
||||
/** |
||||
* alert plugin instance controller |
||||
*/ |
||||
@Api(tags = "ALERT_PLUGIN_INSTANCE_TAG", position = 1) |
||||
@RestController |
||||
@RequestMapping("alert-plugin-instance") |
||||
public class AlertPluginInstanceController extends BaseController { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AlertPluginInstanceController.class); |
||||
|
||||
@Autowired |
||||
private AlertPluginInstanceService alertPluginInstanceService; |
||||
|
||||
|
||||
/** |
||||
* create alert plugin instance |
||||
* |
||||
* @param loginUser login user |
||||
* @param pluginDefineId alert plugin define id |
||||
* @param instanceName instance name |
||||
* @param pluginInstanceParams instance params |
||||
* @return result |
||||
*/ |
||||
@ApiOperation(value = "createAlertPluginInstance", notes = "CREATE_ALERT_PLUGIN_INSTANCE_NOTES") |
||||
@ApiImplicitParams({ |
||||
@ApiImplicitParam(name = "pluginDefineId", value = "ALERT_PLUGIN_DEFINE_ID", required = true, dataType = "Int", example = "100"), |
||||
@ApiImplicitParam(name = "instanceName", value = "ALERT_PLUGIN_INSTANCE_NAME", required = true, dataType = "String", example = "DING TALK"), |
||||
@ApiImplicitParam(name = "pluginInstanceParams", value = "ALERT_PLUGIN_INSTANCE_PARAMS", required = true, dataType = "String", example = "ALERT_PLUGIN_INSTANCE_PARAMS") |
||||
}) |
||||
@PostMapping(value = "/create") |
||||
@ResponseStatus(HttpStatus.CREATED) |
||||
@ApiException(CREATE_ALERT_PLUGIN_INSTANCE_ERROR) |
||||
public Result createAlertPluginInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@RequestParam(value = "pluginDefineId") int pluginDefineId, |
||||
@RequestParam(value = "instanceName") String instanceName, |
||||
@RequestParam(value = "pluginInstanceParams") String pluginInstanceParams) { |
||||
logger.info("login user {},create alert plugin instance, instanceName:{} ", |
||||
StringUtils.replaceNRTtoUnderline(loginUser.getUserName()), |
||||
StringUtils.replaceNRTtoUnderline(instanceName)); |
||||
Map<String, Object> result = alertPluginInstanceService.create(loginUser, pluginDefineId, instanceName, pluginInstanceParams); |
||||
return returnDataList(result); |
||||
} |
||||
|
||||
/** |
||||
* updateAlertPluginInstance |
||||
* |
||||
* @param loginUser login user |
||||
* @param alertPluginInstanceId alert plugin instance id |
||||
* @param instanceName instance name |
||||
* @param pluginInstanceParams instance params |
||||
* @return result |
||||
*/ |
||||
@ApiOperation(value = "update", notes = "UPDATE_ALERT_PLUGIN_INSTANCE_NOTES") |
||||
@ApiImplicitParams({ |
||||
@ApiImplicitParam(name = "alertPluginInstanceId", value = "ALERT_PLUGIN_INSTANCE_ID", required = true, dataType = "Int", example = "100"), |
||||
@ApiImplicitParam(name = "instanceName", value = "ALERT_PLUGIN_INSTANCE_NAME", required = true, dataType = "String", example = "DING TALK"), |
||||
@ApiImplicitParam(name = "pluginInstanceParams", value = "ALERT_PLUGIN_INSTANCE_PARAMS", required = true, dataType = "String", example = "ALERT_PLUGIN_INSTANCE_PARAMS") |
||||
}) |
||||
@GetMapping(value = "/update") |
||||
@ResponseStatus(HttpStatus.OK) |
||||
@ApiException(UPDATE_ALERT_PLUGIN_INSTANCE_ERROR) |
||||
public Result updateAlertPluginInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@RequestParam(value = "alertPluginInstanceId") int alertPluginInstanceId, |
||||
@RequestParam(value = "instanceName") String instanceName, |
||||
@RequestParam(value = "pluginInstanceParams") String pluginInstanceParams) { |
||||
logger.info("login user {},update alert plugin instance id {}", StringUtils.replaceNRTtoUnderline(loginUser.getUserName()), alertPluginInstanceId); |
||||
Map<String, Object> result = alertPluginInstanceService.update(loginUser, alertPluginInstanceId, instanceName, pluginInstanceParams); |
||||
return returnDataList(result); |
||||
} |
||||
|
||||
/** |
||||
* deleteAlertPluginInstance |
||||
* |
||||
* @param loginUser login user |
||||
* @param id id |
||||
* @return result |
||||
*/ |
||||
@ApiOperation(value = "delete", notes = "DELETE_ALERT_PLUGIN_INSTANCE_NOTES") |
||||
@ApiImplicitParams({ |
||||
@ApiImplicitParam(name = "id", value = "ALERT_PLUGIN_ID", required = true, dataType = "Int", example = "100") |
||||
}) |
||||
@GetMapping(value = "/delete") |
||||
@ResponseStatus(HttpStatus.OK) |
||||
@ApiException(DELETE_ALERT_PLUGIN_INSTANCE_ERROR) |
||||
public Result deleteAlertPluginInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@RequestParam(value = "id") int id) { |
||||
logger.info("login user {},delete alert plugin instance id {}", StringUtils.replaceNRTtoUnderline(loginUser.getUserName()), id); |
||||
|
||||
Map<String, Object> result = alertPluginInstanceService.delete(loginUser, id); |
||||
return returnDataList(result); |
||||
} |
||||
|
||||
/** |
||||
* getAlertPluginInstance |
||||
* |
||||
* @param loginUser login user |
||||
* @param id alert plugin instance id |
||||
* @return result |
||||
*/ |
||||
@ApiOperation(value = "get", notes = "GET_ALERT_PLUGIN_INSTANCE_NOTES") |
||||
@PostMapping(value = "/get") |
||||
@ResponseStatus(HttpStatus.OK) |
||||
@ApiException(GET_ALERT_PLUGIN_INSTANCE_ERROR) |
||||
public Result getAlertPluginInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@RequestParam(value = "id") int id) { |
||||
logger.info("login user {},get alert plugin instance, id {}", StringUtils.replaceNRTtoUnderline(loginUser.getUserName()), id); |
||||
Map<String, Object> result = alertPluginInstanceService.get(loginUser, id); |
||||
return returnDataList(result); |
||||
} |
||||
|
||||
/** |
||||
* getAlertPluginInstance |
||||
* |
||||
* @param loginUser login user |
||||
* @return result |
||||
*/ |
||||
@ApiOperation(value = "/queryAll", notes = "QUERY_ALL_ALERT_PLUGIN_INSTANCE_NOTES") |
||||
@PostMapping(value = "/queryAll") |
||||
@ResponseStatus(HttpStatus.OK) |
||||
@ApiException(QUERY_ALL_ALERT_PLUGIN_INSTANCE_ERROR) |
||||
public Result getAlertPluginInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) { |
||||
logger.info("login user {}, query all alert plugin instance", StringUtils.replaceNRTtoUnderline(loginUser.getUserName())); |
||||
Map<String, Object> result = alertPluginInstanceService.queryAll(); |
||||
return returnDataList(result); |
||||
} |
||||
|
||||
/** |
||||
* check alert group exist |
||||
* |
||||
* @param loginUser login user |
||||
* @param alertInstanceName alert instance name |
||||
* @return check result code |
||||
*/ |
||||
@ApiOperation(value = "verifyAlertInstanceName", notes = "VERIFY_ALERT_INSTANCE_NAME_NOTES") |
||||
@ApiImplicitParams({ |
||||
@ApiImplicitParam(name = "groupName", value = "GROUP_NAME", required = true, dataType = "String"), |
||||
}) |
||||
@GetMapping(value = "/verify-alert-instance-name") |
||||
@ResponseStatus(HttpStatus.OK) |
||||
public Result verifyGroupName(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@RequestParam(value = "alertInstanceName") String alertInstanceName) { |
||||
logger.info("login user {},verify alert instance name: {}", StringUtils.replaceNRTtoUnderline(loginUser.getUserName()), StringUtils.replaceNRTtoUnderline(alertInstanceName)); |
||||
|
||||
boolean exist = alertPluginInstanceService.checkExistPluginInstanceName(alertInstanceName); |
||||
Result result = new Result(); |
||||
if (exist) { |
||||
logger.error("alert plugin instance {} has exist, can't create again.", alertInstanceName); |
||||
result.setCode(Status.PLUGIN_INSTANCE_ALREADY_EXIT.getCode()); |
||||
result.setMsg(Status.PLUGIN_INSTANCE_ALREADY_EXIT.getMsg()); |
||||
} else { |
||||
result.setCode(Status.SUCCESS.getCode()); |
||||
result.setMsg(Status.SUCCESS.getMsg()); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* paging query alert plugin instance group list |
||||
* |
||||
* @param loginUser login user |
||||
* @param pageNo page number |
||||
* @param pageSize page size |
||||
* @return alert plugin instance list page |
||||
*/ |
||||
@ApiOperation(value = "queryAlertPluginInstanceListPaging", notes = "QUERY_ALERT_PLUGIN_INSTANCE_LIST_PAGING_NOTES") |
||||
@ApiImplicitParams({ |
||||
@ApiImplicitParam(name = "pageNo", value = "PAGE_NO", dataType = "Int", example = "1"), |
||||
@ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", dataType = "Int", example = "20") |
||||
}) |
||||
@GetMapping(value = "/list-paging") |
||||
@ResponseStatus(HttpStatus.OK) |
||||
@ApiException(LIST_PAGING_ALERT_PLUGIN_INSTANCE_ERROR) |
||||
public Result listPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@RequestParam("pageNo") Integer pageNo, |
||||
@RequestParam("pageSize") Integer pageSize) { |
||||
logger.info("login user {}, list paging, pageNo: {}, pageSize: {}",StringUtils.replaceNRTtoUnderline(loginUser.getUserName()), pageNo, pageSize); |
||||
Map<String, Object> result = checkPageParams(pageNo, pageSize); |
||||
if (result.get(Constants.STATUS) != Status.SUCCESS) { |
||||
return returnDataListPaging(result); |
||||
} |
||||
|
||||
result = alertPluginInstanceService.queryPluginPage(pageNo, pageSize); |
||||
return returnDataListPaging(result); |
||||
} |
||||
|
||||
} |
@ -1,93 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.controller; |
||||
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PLUGINS_ERROR; |
||||
|
||||
import org.apache.dolphinscheduler.api.exceptions.ApiException; |
||||
import org.apache.dolphinscheduler.api.service.UiPluginService; |
||||
import org.apache.dolphinscheduler.api.utils.Result; |
||||
import org.apache.dolphinscheduler.common.Constants; |
||||
import org.apache.dolphinscheduler.common.enums.PluginType; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.http.HttpStatus; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestAttribute; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.springframework.web.bind.annotation.ResponseStatus; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import io.swagger.annotations.Api; |
||||
import io.swagger.annotations.ApiImplicitParam; |
||||
import io.swagger.annotations.ApiImplicitParams; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import springfox.documentation.annotations.ApiIgnore; |
||||
|
||||
/** |
||||
* UiPluginController |
||||
* Some plugins (such as alert plugin) need to provide UI interfaces to users. |
||||
* We use from-creat to dynamically generate UI interfaces. Related parameters are mainly provided by pluginParams. |
||||
* From-create can generate dynamic ui based on this parameter. |
||||
*/ |
||||
@Api(tags = "UI_PLUGINS", position = 1) |
||||
@RestController |
||||
@RequestMapping("ui-plugins") |
||||
public class UiPluginController extends BaseController { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UiPluginController.class); |
||||
|
||||
@Autowired |
||||
UiPluginService uiPluginService; |
||||
|
||||
@ApiOperation(value = "queryUiPluginsByType", notes = "QUERY_UI_PLUGINS_BY_TYPE") |
||||
@ApiImplicitParams({ |
||||
@ApiImplicitParam(name = "pluginType", value = "pluginType", required = true, dataType = "PluginType"), |
||||
}) |
||||
@PostMapping(value = "/queryUiPluginsByType") |
||||
@ResponseStatus(HttpStatus.CREATED) |
||||
@ApiException(QUERY_PLUGINS_ERROR) |
||||
public Result queryUiPluginsByType(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@RequestParam(value = "pluginType") PluginType pluginType) { |
||||
|
||||
logger.info("query plugins by type , pluginType: {}", pluginType); |
||||
Map<String, Object> result = uiPluginService.queryUiPluginsByType(pluginType); |
||||
return returnDataList(result); |
||||
} |
||||
|
||||
@ApiOperation(value = "queryUiPluginDetailById", notes = "QUERY_UI_PLUGIN_DETAIL_BY_ID") |
||||
@ApiImplicitParams({ |
||||
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "PluginType"), |
||||
}) |
||||
@PostMapping(value = "/queryUiPluginDetailById") |
||||
@ResponseStatus(HttpStatus.CREATED) |
||||
@ApiException(QUERY_PLUGINS_ERROR) |
||||
public Result queryUiPluginDetailById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@RequestParam("pluginId") Integer pluginId) { |
||||
|
||||
logger.info("query plugin detail by id , pluginId: {}", pluginId); |
||||
Map<String, Object> result = uiPluginService.queryUiPluginDetailById(pluginId); |
||||
return returnDataList(result); |
||||
} |
||||
} |
@ -1,89 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.service; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* alert plugin instance service |
||||
*/ |
||||
public interface AlertPluginInstanceService { |
||||
|
||||
/** |
||||
* creat alert plugin instance |
||||
* |
||||
* @param loginUser login user |
||||
* @param pluginDefineId plugin define id |
||||
* @param instanceName instance name |
||||
* @param pluginInstanceParams plugin instance params |
||||
* @return result |
||||
*/ |
||||
Map<String, Object> create(User loginUser,int pluginDefineId,String instanceName,String pluginInstanceParams); |
||||
|
||||
/** |
||||
* update |
||||
* @param loginUser login user |
||||
* @param alertPluginInstanceId plugin instance id |
||||
* @param instanceName instance name |
||||
* @param pluginInstanceParams plugin instance params |
||||
* @return result |
||||
*/ |
||||
Map<String, Object> update(User loginUser, int alertPluginInstanceId,String instanceName,String pluginInstanceParams); |
||||
|
||||
/** |
||||
* delete alert plugin instance |
||||
* |
||||
* @param loginUser login user |
||||
* @param id id |
||||
* @return result |
||||
*/ |
||||
Map<String, Object> delete(User loginUser, int id); |
||||
|
||||
/** |
||||
* get alert plugin instance |
||||
* |
||||
* @param loginUser login user |
||||
* @param id get id |
||||
* @return alert plugin |
||||
*/ |
||||
Map<String, Object> get(User loginUser, int id); |
||||
|
||||
/** |
||||
* queryAll |
||||
* |
||||
* @return alert plugins |
||||
*/ |
||||
Map<String, Object> queryAll(); |
||||
|
||||
/** |
||||
* checkExistPluginInstanceName |
||||
* @param pluginName plugin name |
||||
* @return isExist |
||||
*/ |
||||
boolean checkExistPluginInstanceName(String pluginName); |
||||
|
||||
/** |
||||
* queryPluginPage |
||||
* @param pageIndex page index |
||||
* @param pageSize page size |
||||
* @return plugins |
||||
*/ |
||||
Map<String, Object> queryPluginPage(int pageIndex,int pageSize); |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue