This is an automated email from the ASF dual-hosted git repository. xiaoyu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git
The following commit(s) were added to refs/heads/master by this push: new 1f4b575d8 [ISSUE #3133] add alert module (#3311) 1f4b575d8 is described below commit 1f4b575d837ec625923f9243ecaa0d939a0aad2e Author: Sinsy <550569...@qq.com> AuthorDate: Tue Apr 26 18:04:22 2022 +0800 [ISSUE #3133] add alert module (#3311) * add alert module * change pom version * change pom parent * fix ci error * fix ci error * change pom * fix ci error --- pom.xml | 14 ++ shenyu-alert/pom.xml | 59 ++++++ .../apache/shenyu/alert/AlertStrategyFactory.java | 38 ++++ .../java/org/apache/shenyu/alert/DingTalkProp.java | 134 ++++++++++++++ .../java/org/apache/shenyu/alert/EmailProp.java | 204 +++++++++++++++++++++ .../shenyu/alert/strategy/AlertStrategy.java | 35 ++++ .../shenyu/alert/strategy/DingTalkStrategy.java | 75 ++++++++ .../shenyu/alert/strategy/EmailStrategy.java | 99 ++++++++++ .../org.apache.shenyu.alert.strategy.AlertStrategy | 17 ++ 9 files changed, 675 insertions(+) diff --git a/pom.xml b/pom.xml index b39073a80..6e7cd1b1a 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,7 @@ <module>shenyu-protocol</module> <module>shenyu-loadbalancer</module> <module>shenyu-dist</module> + <module>shenyu-alert</module> </modules> <licenses> @@ -146,6 +147,7 @@ <jaxb.api.version>2.3.0</jaxb.api.version> <spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version> <netflix-ribbon.version>2.2.9.RELEASE</netflix-ribbon.version> + <mail.version>1.6.2</mail.version> <dockerfile-maven-plugin.version>1.4.6</dockerfile-maven-plugin.version> </properties> @@ -398,6 +400,18 @@ <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>${netflix-ribbon.version}</version> </dependency> + + <dependency> + <groupId>javax.mail</groupId> + <artifactId>javax.mail-api</artifactId> + <version>${mail.version}</version> + </dependency> + <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + <version>${mail.version}</version> + </dependency> + </dependencies> </dependencyManagement> diff --git a/shenyu-alert/pom.xml b/shenyu-alert/pom.xml new file mode 100644 index 000000000..d7e6c9f39 --- /dev/null +++ b/shenyu-alert/pom.xml @@ -0,0 +1,59 @@ +<?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> + <groupId>org.apache.shenyu</groupId> + <artifactId>shenyu</artifactId> + <version>2.5.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>shenyu-alert</artifactId> + + <dependencies> + + <dependency> + <groupId>org.apache.shenyu</groupId> + <artifactId>shenyu-spi</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.shenyu</groupId> + <artifactId>shenyu-common</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + </dependency> + + <dependency> + <groupId>javax.mail</groupId> + <artifactId>javax.mail-api</artifactId> + </dependency> + + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>okhttp</artifactId> + <version>${okhttp.version}</version> + </dependency> + + </dependencies> + +</project> \ No newline at end of file diff --git a/shenyu-alert/src/main/java/org/apache/shenyu/alert/AlertStrategyFactory.java b/shenyu-alert/src/main/java/org/apache/shenyu/alert/AlertStrategyFactory.java new file mode 100644 index 000000000..3f78bf657 --- /dev/null +++ b/shenyu-alert/src/main/java/org/apache/shenyu/alert/AlertStrategyFactory.java @@ -0,0 +1,38 @@ +/* + * 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.shenyu.alert; + +import org.apache.shenyu.alert.strategy.AlertStrategy; +import org.apache.shenyu.spi.ExtensionLoader; + +/** + * The type alert strategy factory. + */ +public class AlertStrategyFactory { + + /** + * New instance alert strategy. + * + * @param strategyName the strategy name + * @return the alert strategy + */ + public static AlertStrategy newInstance(final String strategyName) { + return ExtensionLoader.getExtensionLoader(AlertStrategy.class).getJoin(strategyName); + } + +} diff --git a/shenyu-alert/src/main/java/org/apache/shenyu/alert/DingTalkProp.java b/shenyu-alert/src/main/java/org/apache/shenyu/alert/DingTalkProp.java new file mode 100644 index 000000000..b5216f80d --- /dev/null +++ b/shenyu-alert/src/main/java/org/apache/shenyu/alert/DingTalkProp.java @@ -0,0 +1,134 @@ +/* + * 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.shenyu.alert; + +import java.util.List; + +/** + * DingTalk Prop. + */ +public class DingTalkProp { + + private String url; + + private List<String> atMobiles; + + private List<String> atUserIds; + + private String msgtype; + + private String content; + + private Boolean isAtAll = false; + + /** + * get url. + * @return url + */ + public String getUrl() { + return url; + } + + /** + * set url. + * @param url url + */ + public void setUrl(final String url) { + this.url = url; + } + + /** + * get atMobiles. + * @return atMobiles + */ + public List<String> getAtMobiles() { + return atMobiles; + } + + /** + * set atMobiles. + * @param atMobiles atMobiles + */ + public void setAtMobiles(final List<String> atMobiles) { + this.atMobiles = atMobiles; + } + + /** + * get atUserIds. + * @return atUserIds + */ + public List<String> getAtUserIds() { + return atUserIds; + } + + /** + * set atUserIds. + * @param atUserIds atUserIds + */ + public void setAtUserIds(final List<String> atUserIds) { + this.atUserIds = atUserIds; + } + + /** + * get msgtype. + * @return msgtype + */ + public String getMsgtype() { + return msgtype; + } + + /** + * set msgtype. + * @param msgtype msgtype + */ + public void setMsgtype(final String msgtype) { + this.msgtype = msgtype; + } + + /** + * get content. + * @return content + */ + public String getContent() { + return content; + } + + /** + * set content. + * @param content content + */ + public void setContent(final String content) { + this.content = content; + } + + /** + * get isAtAll. + * @return isAtAll + */ + public Boolean getAtAll() { + return isAtAll; + } + + /** + * set atAll. + * @param atAll atAll + */ + public void setAtAll(final Boolean atAll) { + isAtAll = atAll; + } +} diff --git a/shenyu-alert/src/main/java/org/apache/shenyu/alert/EmailProp.java b/shenyu-alert/src/main/java/org/apache/shenyu/alert/EmailProp.java new file mode 100644 index 000000000..48b5e9054 --- /dev/null +++ b/shenyu-alert/src/main/java/org/apache/shenyu/alert/EmailProp.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shenyu.alert; + +/** + * Email Prop. + */ +public class EmailProp { + + private String to; + + private String subject; + + private String from; + + private String host; + + private Integer port = 25; + + private Boolean auth = false; + + private Boolean enableTls = false; + + private String userName; + + private String password; + + private String text; + + /** + * get to. + * @return to + */ + public String getTo() { + return to; + } + + /** + * set to. + * @param to to + */ + public void setTo(final String to) { + this.to = to; + } + + /** + * get subject. + * @return subject + */ + public String getSubject() { + return subject; + } + + /** + * set subject. + * @param subject subject + */ + public void setSubject(final String subject) { + this.subject = subject; + } + + /** + * get from. + * @return from + */ + public String getFrom() { + return from; + } + + /** + * set from. + * @param from from + */ + public void setFrom(final String from) { + this.from = from; + } + + /** + * get host. + * @return host + */ + public String getHost() { + return host; + } + + /** + * set host. + * @param host host + */ + public void setHost(final String host) { + this.host = host; + } + + /** + * get port default 25. + * @return port + */ + public Integer getPort() { + return port; + } + + /** + * set port. + * @param port port + */ + public void setPort(final Integer port) { + this.port = port; + } + + /** + * get auth default false. + * @return auth. + */ + public Boolean getAuth() { + return auth; + } + + /** + * set auth. + * @param auth auth + */ + public void setAuth(final Boolean auth) { + this.auth = auth; + } + + /** + * get enableTls default false. + * @return enableTls + */ + public Boolean getEnableTls() { + return enableTls; + } + + /** + * set enableTls. + * @param enableTls enableTls + */ + public void setEnableTls(final Boolean enableTls) { + this.enableTls = enableTls; + } + + /** + * get userName. + * @return userName + */ + public String getUserName() { + return userName; + } + + /** + * set userName. + * @param userName userName + */ + public void setUserName(final String userName) { + this.userName = userName; + } + + /** + * get password. + * @return password + */ + public String getPassword() { + return password; + } + + /** + * set password. + * @param password password + */ + public void setPassword(final String password) { + this.password = password; + } + + /** + * get text. + * @return text + */ + public String getText() { + return text; + } + + /** + * set text. + * @param text text + */ + public void setText(final String text) { + this.text = text; + } +} diff --git a/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/AlertStrategy.java b/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/AlertStrategy.java new file mode 100644 index 000000000..50152edaf --- /dev/null +++ b/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/AlertStrategy.java @@ -0,0 +1,35 @@ +/* + * 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.shenyu.alert.strategy; + +import org.apache.shenyu.spi.SPI; + +/** + * alert strategy. + */ +@SPI +public interface AlertStrategy { + + /** + * Alert executor. + * + * @param handle json handle + * @throws Exception Exception + */ + void execute(String handle) throws Exception; +} diff --git a/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/DingTalkStrategy.java b/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/DingTalkStrategy.java new file mode 100644 index 000000000..e201650f0 --- /dev/null +++ b/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/DingTalkStrategy.java @@ -0,0 +1,75 @@ +/* + * 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.shenyu.alert.strategy; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import org.apache.shenyu.alert.DingTalkProp; +import org.apache.shenyu.common.utils.GsonUtils; +import org.apache.shenyu.spi.Join; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * dingTalk strategy. + */ +@Join +public class DingTalkStrategy implements AlertStrategy { + + private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient() + .newBuilder().connectTimeout(50L, TimeUnit.SECONDS) + .readTimeout(60L, TimeUnit.SECONDS) + .build(); + + @Override + public void execute(final String handle) throws Exception { + + DingTalkProp dingTalkProp = GsonUtils.getInstance().fromJson(handle, DingTalkProp.class); + + RequestBody body = RequestBody.create( + MediaType.parse("application/json"), toJson(dingTalkProp)); + Request request = new Request.Builder() + .url(dingTalkProp.getUrl()) + .post(body) + .build(); + OK_HTTP_CLIENT.newCall(request).execute(); + } + + private String toJson(final DingTalkProp prop) { + + Map<String, String> contentMap = new HashMap<>(4); + contentMap.put("content", prop.getContent()); + + Map<String, Object> atMap = new HashMap<>(8); + atMap.put("atMobiles", prop.getAtMobiles()); + atMap.put("atUserIds", prop.getAtUserIds()); + atMap.put("isAtAll", prop.getAtAll()); + + Map<String, Object> body = new HashMap<>(8); + + body.put("at", atMap); + body.put("msgtype", "text"); + body.put("text", contentMap); + return GsonUtils.getInstance().toJson(body); + } + +} diff --git a/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/EmailStrategy.java b/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/EmailStrategy.java new file mode 100644 index 000000000..dbab4dd85 --- /dev/null +++ b/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/EmailStrategy.java @@ -0,0 +1,99 @@ +/* + * 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.shenyu.alert.strategy; + +import org.apache.shenyu.alert.EmailProp; +import org.apache.shenyu.common.utils.GsonUtils; +import org.apache.shenyu.spi.Join; + +import javax.mail.Authenticator; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.MessagingException; +import javax.mail.Message; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.util.Properties; + +/** + * email strategy. + */ +@Join +public class EmailStrategy implements AlertStrategy { + + @Override + public void execute(final String handle) throws Exception { + EmailProp email = GsonUtils.getInstance().fromJson(handle, EmailProp.class); + Properties props = props(email); + + Session session = session(email, props); + + MimeMessage message = message(email, session); + + Transport.send(message); + + } + + /** + * create configuration properties. + * + * @param emailProp email properties. + * @return email properties + */ + private Properties props(final EmailProp emailProp) { + Properties props = new Properties(); + props.put("mail.smtp.host", emailProp.getHost()); + props.put("mail.smtp.port", emailProp.getPort()); + props.put("mail.smtp.auth", emailProp.getAuth()); + props.put("mail.smtp.starttls.enable", emailProp.getEnableTls()); + + return props; + } + + /** + * create session. + * @param emailProp emailProp + * @param props props + * @return Session + */ + private Session session(final EmailProp emailProp, final Properties props) { + return Session.getInstance(props, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(emailProp.getUserName(), emailProp.getPassword()); + } + }); + } + + /** + * create message. + * @param prop prop + * @param session session + * @return MimeMessage + * @throws MessagingException MessagingException + */ + private MimeMessage message(final EmailProp prop, final Session session) throws MessagingException { + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress(prop.getFrom())); + message.setRecipient(Message.RecipientType.TO, new InternetAddress(prop.getTo())); + message.setSubject(prop.getSubject(), "UTF-8"); + message.setText(prop.getText(), "UTF-8"); + return message; + } +} diff --git a/shenyu-alert/src/main/resources/META-INF/shenyu/org.apache.shenyu.alert.strategy.AlertStrategy b/shenyu-alert/src/main/resources/META-INF/shenyu/org.apache.shenyu.alert.strategy.AlertStrategy new file mode 100644 index 000000000..78d304ee0 --- /dev/null +++ b/shenyu-alert/src/main/resources/META-INF/shenyu/org.apache.shenyu.alert.strategy.AlertStrategy @@ -0,0 +1,17 @@ +# 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. +dingTalk=org.apache.shenyu.alert.strategy.DingTalkStrategy +email=org.apache.shenyu.alert.strategy.EmailStrategy