Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature]Support config email server on web-ui #954

Merged
merged 15 commits into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,10 @@
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<!-- kafka -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.dromara.hertzbeat.common.entity.manager;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import java.time.LocalDateTime;

import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY;
import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE;

/**
* 消息通知服务端配置实体
* @author zqr10159
*/
@Entity
@Table(name = "hzb_config")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "Message notification server config entity | 消息通知服务端配置实体")
@EntityListeners(AuditingEntityListener.class)
public class GeneralConfig {

@Id
@Schema(title = "Config type: 1-SMS 2-Email, primary key ", description = "配置类型: 1-短信 2-邮件, 主键",
accessMode = READ_WRITE)
@Min(1)
@NotNull
private Byte type;

@Schema(title = "Config content", description = "配置内容,格式为json", accessMode = READ_WRITE)
@Column(length = 4096)
private String content;

@Schema(title = "Whether to enable this policy",
description = "是否启用此配置",
example = "true", accessMode = READ_WRITE)
private boolean enable = true;

@Schema(title = "The creator of this record", description = "此条记录创建者", example = "tom", accessMode = READ_ONLY)
@CreatedBy
private String creator;

@Schema(title = "This record was last modified by",
description = "此条记录最新修改者",
example = "tom", accessMode = READ_ONLY)
@LastModifiedBy
private String modifier;

@Schema(title = "This record creation time (millisecond timestamp)",
description = "记录创建时间", accessMode = READ_ONLY)
@CreatedDate
private LocalDateTime gmtCreate;

@Schema(title = "Record the latest modification time (timestamp in milliseconds)",
description = "记录最新修改时间", accessMode = READ_ONLY)
@LastModifiedDate
private LocalDateTime gmtUpdate;
}
6 changes: 6 additions & 0 deletions manager/data/hzb_config.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CREATE TABLE `hzb_config` (
`type` tinyint(5) NOT NULL COMMENT '配置类型:1-短信,2-邮件',
`content` json DEFAULT NULL COMMENT '配置内容',
`enabled` tinyint(1) DEFAULT NULL COMMENT '标志位,使用原生配置为0,使用数据库配置为1',
PRIMARY KEY (`type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;
Expand All @@ -29,7 +30,7 @@
*
*/

@SpringBootApplication
@SpringBootApplication(exclude = MailSenderAutoConfiguration.class)
@EnableJpaAuditing
@EnableScheduling
@EnableJpaRepositories(basePackages = {"org.dromara.hertzbeat"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,28 @@

package org.dromara.hertzbeat.manager.component.alerter.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hertzbeat.common.entity.alerter.Alert;
import org.dromara.hertzbeat.common.entity.manager.GeneralConfig;
import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver;
import org.dromara.hertzbeat.common.util.ResourceBundleUtil;
import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler;
import org.dromara.hertzbeat.manager.config.MailConfigProperties;
import org.dromara.hertzbeat.manager.dao.GeneralConfigDao;
import org.dromara.hertzbeat.manager.pojo.dto.NoticeSender;
import org.dromara.hertzbeat.manager.service.MailService;
import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;
import java.util.ResourceBundle;

/**
Expand All @@ -42,19 +48,54 @@
@Component
@RequiredArgsConstructor
@Slf4j
@ConditionalOnProperty("spring.mail.username")
final class EmailAlertNotifyHandlerImpl implements AlertNotifyHandler {

private final JavaMailSender javaMailSender;

private final MailConfigProperties mailConfigProperties;

private final MailService mailService;

@Value("${spring.mail.username}")
private String emailFromUser;

private final GeneralConfigDao generalConfigDao;

private final ObjectMapper objectMapper;

private static final Byte TYPE = 2;

private final ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter");

@Override
public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException {
try {
//获取sender
JavaMailSenderImpl sender = (JavaMailSenderImpl) javaMailSender;
try {
GeneralConfig emailConfig = generalConfigDao.findByType(TYPE);
if (emailConfig != null && emailConfig.isEnable() && emailConfig.getContent() != null) {
// 若启用数据库配置
String content = emailConfig.getContent();
NoticeSender noticeSenderConfig = objectMapper.readValue(content, NoticeSender.class);
sender.setHost(noticeSenderConfig.getEmailHost());
sender.setPort(noticeSenderConfig.getEmailPort());
sender.setUsername(noticeSenderConfig.getEmailUsername());
sender.setPassword(noticeSenderConfig.getEmailPassword());
Properties props = sender.getJavaMailProperties();
props.put("spring.mail.smtp.ssl.enable", noticeSenderConfig.isEmailSsl());
emailFromUser = noticeSenderConfig.getEmailUsername();
} else {
// 若数据库未配置则启用yml配置
sender.setHost(mailConfigProperties.getHost());
sender.setPort(mailConfigProperties.getPort());
sender.setUsername(mailConfigProperties.getUsername());
sender.setPassword(mailConfigProperties.getPassword());
emailFromUser = mailConfigProperties.getUsername();
}
} catch (Exception e) {
log.error("Type not found {}",e.getMessage());
}
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
messageHelper.setSubject(bundle.getString("alerter.notify.title"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.dromara.hertzbeat.manager.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Component;

import java.util.Properties;

/**
*
* @author zqr10159
*/

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "spring.mail")
public class MailConfigProperties {
private String host;
private String username;
private String password;
private Integer port;
private boolean ssl;

@Bean
public JavaMailSender javaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(host);
mailSender.setPort(port);
mailSender.setUsername(username);
mailSender.setPassword(password);

Properties props = mailSender.getJavaMailProperties();
props.put("spring.mail.smtp.ssl.enable", ssl);
props.put("spring.mail.smtp.socketFactory.port", port);
props.put("spring.mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("spring.mail.debug", "false");
props.put("spring.mail.default-encoding", "UTF-8");

return mailSender;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.dromara.hertzbeat.manager.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hertzbeat.common.entity.dto.Message;
import org.dromara.hertzbeat.manager.pojo.dto.NoticeSender;
import org.dromara.hertzbeat.manager.service.impl.MailGeneralConfigServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


import javax.validation.Valid;

import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

/**
* Alert sender Configuration API
* 告警发送端配置API
*
* @author zqr10159
*
*/
@RestController
@RequestMapping(value = "/api/config", produces = {APPLICATION_JSON_VALUE})
@Tag(name = "Alert sender Configuration API | 告警发送端配置API")
@Slf4j
public class NoticeSenderConfigController {
@Autowired
private MailGeneralConfigServiceImpl mailConfigService;

@PostMapping(path = "/sender")
@Operation(summary = "Save the sender config", description = "保存发送端配置")
public ResponseEntity<Message<String>> saveOrUpdateConfig(
@RequestBody @Valid NoticeSender noticeSender) {
mailConfigService.saveConfig(noticeSender, noticeSender.isEmailEnable());
return ResponseEntity.ok(new Message<>("发送端配置保存成功|The sender configuration is saved successfully"));
}

@GetMapping(path = "/senders")
@Operation(summary = "Get the sender config", description = "获取发送端配置")
public ResponseEntity<Message<List<NoticeSender>>> getConfig(){
List<NoticeSender> senders = mailConfigService.getConfigs();
return ResponseEntity.ok(new Message<>(senders));
}

@DeleteMapping(path = "/sender/{id}")
@Operation(summary = "Delete the sender config", description = "删除发送端配置")
public ResponseEntity<Message<String>> deleteConfig(){
mailConfigService.deleteConfig();
return ResponseEntity.ok(new Message<>("发送端配置删除成功|The sender configuration is deleted"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.dromara.hertzbeat.manager.dao;

import org.dromara.hertzbeat.common.entity.manager.GeneralConfig;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Component;

/**
* 消息通知服务端配置Dao
*
* <p>该接口继承了JpaRepository和JpaSpecificationExecutor两个接口,提供基本的CRUD操作和规范查询能力。</p>
*
* @version 1.0
* @since 2023/5/9 22:39
* @author zqr10159
*/
@Component
public interface GeneralConfigDao extends JpaRepository<GeneralConfig, Long>, JpaSpecificationExecutor<GeneralConfig> {

/**
* 通过类型删除
*
* @param type 类型
* @return 返回受影响的行数
*/
int deleteByType(Byte type);

/**
* 通过类型查询
*
* @param type 类型
* @return 返回查询到的配置信息
*/
GeneralConfig findByType(Byte type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.dromara.hertzbeat.manager.pojo.dto;

import lombok.Data;

import javax.validation.constraints.*;


/**
* 邮件账号配置dto
* @author zqr
*/
@Data
public class NoticeSender {

@NotNull(message = "类型不能为空|Type cannot be empty")
private Integer type;

@NotBlank(message = "邮件主机不能为空|Mail host cannot be empty")
private String emailHost;

@NotBlank(message = "用户名不能为空|Username cannot be empty")
@Email
private String emailUsername;

@NotBlank(message = "密码不能为空|Password cannot be empty")
private String emailPassword;

@NotNull(message = "邮件端口不能为空|Mail port cannot be null")
@Max(message = "邮件端口不得大于65535|Mail port must be less than or equal to 65535", value = 65535)
@Min(message = "邮件端口不得小于1|Mail port must be greater than or equal to 1", value = 1)
private Integer emailPort;

private boolean emailSsl;

private boolean emailEnable;
}
Loading