Merge remote-tracking branch 'origin/dev-V0.5.0' into dev-V0.5.0

V0.5.x
tangfudong 2024-01-02 10:46:02 +08:00
commit 4a1ae2d75a
34 changed files with 271 additions and 225 deletions

View File

@ -19,8 +19,7 @@
"channelId": 1, "channelId": 1,
"title": "告警钉钉配置", "title": "告警钉钉配置",
"param": { "param": {
"dingTalkWebhook":"xxxxxxxxxxxxxxxx", "dingTalkWebhook":"xxxxxxxxxxxxxxxx"
"dingTalkSecret":"xxxx"
}, },
"createAt": 1683816661690 "createAt": 1683816661690
}, },

View File

@ -49,7 +49,7 @@ public class AlertConfig implements Owned<Long> {
/** /**
* ID * ID
*/ */
private String messageTemplateId; private Long messageTemplateId;
/** /**
* *

View File

@ -1,14 +1,11 @@
package cc.iotkit.model.notify; package cc.iotkit.model.notify;
import cc.iotkit.model.Id; import cc.iotkit.model.Id;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.io.Serializable;
/** /**
* author: * author:
* date: 2023-05-11 16:30 * date: 2023-05-11 16:30
@ -26,23 +23,8 @@ public class ChannelConfig implements Id<Long> {
private String title; private String title;
private ChannelParam param; private String param;
private Long createAt; private Long createAt;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class ChannelParam implements Serializable {
private String userName;
private String passWord;
private String host;
private Integer port;
private Boolean mailSmtpAuth;
private String from;
private String to;
private String dingTalkWebhook;
private String dingTalkSecret;
private String qyWechatWebhook;
}
} }

View File

@ -11,7 +11,8 @@ package cc.iotkit.data.dao;
import cc.iotkit.data.model.TbAlertRecord; import cc.iotkit.data.model.TbAlertRecord;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
public interface AlertRecordRepository extends JpaRepository<TbAlertRecord, Long> { public interface AlertRecordRepository extends JpaRepository<TbAlertRecord, Long>, QuerydslPredicateExecutor<TbAlertRecord> {
} }

View File

@ -1,44 +0,0 @@
package cc.iotkit.data.model;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.model.notify.ChannelConfig;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import java.util.Objects;
/**
* @Author:
* @Date: 2023/5/11 21:02
* @Description:
*/
@Mapper(componentModel = "spring")
public interface ChannelConfigMapper {
@Mappings({
@Mapping(target = "param", expression = "java(stingToParam(vo.getParam()))")
})
ChannelConfig toDto(TbChannelConfig vo);
@Mappings({
@Mapping(target = "param", expression = "java(paramToSting(dto.getParam()))")
})
TbChannelConfig toVo(ChannelConfig dto);
default String paramToSting(ChannelConfig.ChannelParam param) {
if (Objects.isNull(param)) {
return null;
}
return JsonUtils.toJsonString(param);
}
default ChannelConfig.ChannelParam stingToParam(String param) {
if (Objects.isNull(param)) {
return null;
}
return JsonUtils.parse(param, ChannelConfig.ChannelParam.class);
}
}

View File

@ -1,6 +1,6 @@
package cc.iotkit.data.model; package cc.iotkit.data.model;
import cc.iotkit.model.alert.AlertConfig; import cc.iotkit.model.alert.AlertRecord;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -13,9 +13,8 @@ import javax.persistence.Table;
@Data @Data
@Entity @Entity
//@ApiModel(value = "告警记录")
@Table(name = "alert_record") @Table(name = "alert_record")
@AutoMapper(target= AlertConfig.class) @AutoMapper(target = AlertRecord.class)
public class TbAlertRecord { public class TbAlertRecord {
@Id @Id

View File

@ -3,11 +3,19 @@ package cc.iotkit.data.service;
import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging; import cc.iotkit.common.api.Paging;
import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.data.dao.AlertRecordRepository; import cc.iotkit.data.dao.AlertRecordRepository;
import cc.iotkit.data.dao.IJPACommData; import cc.iotkit.data.dao.IJPACommData;
import cc.iotkit.data.manager.IAlertRecordData; import cc.iotkit.data.manager.IAlertRecordData;
import cc.iotkit.data.model.TbAlertRecord; import cc.iotkit.data.model.TbAlertRecord;
import cc.iotkit.data.util.PageBuilder;
import cc.iotkit.data.util.PredicateBuilder;
import cc.iotkit.model.alert.AlertRecord; import cc.iotkit.model.alert.AlertRecord;
import cc.iotkit.model.system.SysLoginInfo;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -15,6 +23,8 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import static cc.iotkit.data.model.QTbAlertRecord.tbAlertRecord;
@Primary @Primary
@Service @Service
public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData<AlertRecord, Long> { public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData<AlertRecord, Long> {
@ -22,6 +32,8 @@ public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData<Alert
@Autowired @Autowired
private AlertRecordRepository alertRecordRepository; private AlertRecordRepository alertRecordRepository;
@Autowired
private JPAQueryFactory jpaQueryFactory;
@Override @Override
public JpaRepository getBaseRepository() { public JpaRepository getBaseRepository() {
@ -38,12 +50,19 @@ public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData<Alert
return AlertRecord.class; return AlertRecord.class;
} }
private static Predicate genPredicate(AlertRecord data) {
return PredicateBuilder.instance()
.and(StringUtils.isNotBlank(data.getName()), () -> tbAlertRecord.name.like(data.getName()))
.and(StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel()))
.build();
}
@Override @Override
public Paging<AlertRecord> selectAlertConfigPage(PageRequest<AlertRecord> request) { public Paging<AlertRecord> selectAlertConfigPage(PageRequest<AlertRecord> request) {
Page<TbAlertRecord> alertRecordPage = alertRecordRepository.findAll(Pageable.ofSize(request.getPageSize()) QueryResults<TbAlertRecord> results = jpaQueryFactory.selectFrom(tbAlertRecord).where(genPredicate(request.getData()))
.withPage(request.getPageNum() - 1)); .orderBy(tbAlertRecord.id.desc())
return new Paging<>(alertRecordPage.getTotalElements(), .limit(request.getPageSize())
MapstructUtils.convert(alertRecordPage.getContent(), AlertRecord.class)); .offset(request.getOffset()).fetchResults();
return new Paging<>(results.getTotal(), results.getResults()).to(AlertRecord.class);
} }
} }

View File

@ -5,7 +5,6 @@ import cc.iotkit.common.api.Paging;
import cc.iotkit.data.dao.ChannelConfigRepository; import cc.iotkit.data.dao.ChannelConfigRepository;
import cc.iotkit.data.dao.IJPACommData; import cc.iotkit.data.dao.IJPACommData;
import cc.iotkit.data.manager.IChannelConfigData; import cc.iotkit.data.manager.IChannelConfigData;
import cc.iotkit.data.model.ChannelConfigMapper;
import cc.iotkit.data.model.TbChannelConfig; import cc.iotkit.data.model.TbChannelConfig;
import cc.iotkit.model.notify.ChannelConfig; import cc.iotkit.model.notify.ChannelConfig;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
@ -15,7 +14,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.stream.Collectors;
/** /**
* author: * author:
@ -29,9 +27,6 @@ public class ChannelConfigDataImpl implements IChannelConfigData, IJPACommData<C
@Resource @Resource
private ChannelConfigRepository channelConfigRepository; private ChannelConfigRepository channelConfigRepository;
@Resource
private ChannelConfigMapper channelConfigMapper;
@Override @Override
public JpaRepository getBaseRepository() { public JpaRepository getBaseRepository() {
return channelConfigRepository; return channelConfigRepository;
@ -53,8 +48,6 @@ public class ChannelConfigDataImpl implements IChannelConfigData, IJPACommData<C
return new Paging<>( return new Paging<>(
tbChannelConfigs.getTotalElements(), tbChannelConfigs.getTotalElements(),
tbChannelConfigs.getContent() tbChannelConfigs.getContent()
.stream().map(channelConfigMapper::toDto) ).to(ChannelConfig.class);
.collect(Collectors.toList())
);
} }
} }

View File

@ -3,7 +3,6 @@ package cc.iotkit.manager.dto.bo.channel;
import cc.iotkit.common.api.BaseDto; import cc.iotkit.common.api.BaseDto;
import cc.iotkit.model.notify.ChannelConfig; import cc.iotkit.model.notify.ChannelConfig;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMapping;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -13,7 +12,7 @@ import lombok.EqualsAndHashCode;
@ApiModel(value = "ChannelConfigBo") @ApiModel(value = "ChannelConfigBo")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ChannelConfig.class, reverseConvertGenerate = false) @AutoMapper(target = ChannelConfig.class)
public class ChannelConfigBo extends BaseDto { public class ChannelConfigBo extends BaseDto {
private static final long serialVersionUID = -1L; private static final long serialVersionUID = -1L;
@ -28,7 +27,6 @@ public class ChannelConfigBo extends BaseDto {
private String title; private String title;
@ApiModelProperty(value="通道配置参数") @ApiModelProperty(value="通道配置参数")
@AutoMapping(target = "param", expression = "java(cc.iotkit.common.utils.JsonUtils.parse(source.getParam(), ChannelConfig.ChannelParam.class))")
private String param; private String param;
@ApiModelProperty(value="创建时间") @ApiModelProperty(value="创建时间")

View File

@ -4,8 +4,6 @@ import cc.iotkit.model.notify.ChannelConfig;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMapping;
import io.github.linpeilie.annotations.ReverseAutoMapping;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -34,8 +32,6 @@ public class ChannelConfigVo implements Serializable {
@ApiModelProperty(value="通道配置参数") @ApiModelProperty(value="通道配置参数")
@ExcelProperty(value = "通道配置参数") @ExcelProperty(value = "通道配置参数")
@ReverseAutoMapping(target = "param", expression = "java(cc.iotkit.common.utils.JsonUtils.toJsonString(source.getParam()))")
@AutoMapping(target = "param", expression = "java(cc.iotkit.common.utils.JsonUtils.parse(source.getParam(), ChannelConfig.ChannelParam.class))")
private String param; private String param;
@ApiModelProperty(value="创建时间") @ApiModelProperty(value="创建时间")

View File

@ -0,0 +1,33 @@
package cc.iotkit.manager.service;
import cc.iotkit.data.manager.IAlertConfigData;
import cc.iotkit.message.event.MessageEvent;
import cc.iotkit.message.listener.MessageEventListener;
import cc.iotkit.message.model.Message;
import cc.iotkit.model.alert.AlertConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
* @author sjg
*/
@Slf4j
@Component
public class AlertMessageEventListener implements MessageEventListener {
@Autowired
private IAlertConfigData alertConfigData;
@Autowired
private AlertService alertService;
@Override
@EventListener(classes = MessageEvent.class)
public void doEvent(MessageEvent event) {
Message message = event.getMessage();
AlertConfig alertConfig = alertConfigData.findById(message.getAlertConfigId());
alertService.addAlert(alertConfig, message.getFormatContent());
}
}

View File

@ -38,7 +38,7 @@ public class AlertService {
} }
public void deleteAlertConfigById(Long id) { public void deleteAlertConfigById(Long id) {
alertConfigData.deleteById(id); alertConfigData.deleteById(id);
} }
public Paging<AlertConfig> selectAlertConfigPage(PageRequest<AlertConfig> request) { public Paging<AlertConfig> selectAlertConfigPage(PageRequest<AlertConfig> request) {
@ -48,4 +48,14 @@ public class AlertService {
public Paging<AlertRecord> selectAlertRecordPage(PageRequest<AlertRecord> request) { public Paging<AlertRecord> selectAlertRecordPage(PageRequest<AlertRecord> request) {
return alertRecordData.selectAlertConfigPage(request); return alertRecordData.selectAlertConfigPage(request);
} }
public void addAlert(AlertConfig config, String content) {
alertRecordData.save(AlertRecord.builder()
.level(config.getLevel())
.name(config.getName())
.readFlg(false)
.alertTime(System.currentTimeMillis())
.details(content)
.build());
}
} }

View File

@ -13,6 +13,11 @@
<dependencies> <dependencies>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-core</artifactId>
</dependency>
<dependency> <dependency>
<groupId>io.vertx</groupId> <groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId> <artifactId>vertx-web-client</artifactId>

View File

@ -1,6 +1,9 @@
package cc.iotkit.message.listener; package cc.iotkit.message.listener;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.message.config.VertxManager; import cc.iotkit.message.config.VertxManager;
import cc.iotkit.message.event.MessageEvent;
import cc.iotkit.message.model.DingTalkConfig;
import cc.iotkit.message.model.DingTalkMessage; import cc.iotkit.message.model.DingTalkMessage;
import cc.iotkit.message.model.Message; import cc.iotkit.message.model.Message;
import io.vertx.ext.web.client.WebClient; import io.vertx.ext.web.client.WebClient;
@ -16,18 +19,20 @@ import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@Component @Component
public class DingTalkEventListener implements MessageEventListener { public class DingTalkEventListener implements MessageEventListener {
private String baseUrl = "https://oapi.dingtalk.com/robot/send?access_token=%s";
@Override @Override
@EventListener(condition = "message.channel()='DingTalk'") @EventListener(classes = MessageEvent.class, condition = "#event.message.channel=='DingTalk'")
public void doEvent(Message message) { public void doEvent(MessageEvent event) {
Message message = event.getMessage();
String channelConfig = message.getChannelConfig();
DingTalkConfig dingTalkConfig = JsonUtils.parse(channelConfig, DingTalkConfig.class);
WebClient client = WebClient.create(VertxManager.INSTANCE.getVertx()); WebClient client = WebClient.create(VertxManager.INSTANCE.getVertx());
String url = String.format(baseUrl, message.getKey());
DingTalkMessage qyWechatMessage = DingTalkMessage.builder() DingTalkMessage qyWechatMessage = DingTalkMessage.builder()
.msgtype("text") .msgtype("text")
.text(DingTalkMessage.MessageContent.builder().content(getContent(message)).build()) .text(DingTalkMessage.MessageContent.builder().content(message.getFormatContent()).build())
.build(); .build();
client.post(url).sendJson(qyWechatMessage) client.post(dingTalkConfig.getDingTalkWebhook()).sendJson(qyWechatMessage)
.onSuccess(response -> log.info("Received response with status code" + response.statusCode())) .onSuccess(response -> log.info("Received response with status code" + response.statusCode()))
.onFailure(err -> log.error("Something went wrong " + err.getMessage())); .onFailure(err -> log.error("Something went wrong " + err.getMessage()));
} }

View File

@ -1,5 +1,7 @@
package cc.iotkit.message.listener; package cc.iotkit.message.listener;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.message.event.MessageEvent;
import cc.iotkit.message.model.EmailConfig; import cc.iotkit.message.model.EmailConfig;
import cc.iotkit.message.model.Message; import cc.iotkit.message.model.Message;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -8,7 +10,6 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import java.util.Properties; import java.util.Properties;
@ -22,9 +23,12 @@ import java.util.Properties;
public class EmailEventListener implements MessageEventListener { public class EmailEventListener implements MessageEventListener {
@Override @Override
@EventListener(condition = "message.channel()='Email'") @EventListener(classes = MessageEvent.class, condition = "#event.message.channel=='Email'")
public void doEvent(Message message) { public void doEvent(MessageEvent event) {
EmailConfig emailConfig = new EmailConfig(); Message message = event.getMessage();
String channelConfig = message.getChannelConfig();
EmailConfig emailConfig = JsonUtils.parse(channelConfig, EmailConfig.class);
JavaMailSenderImpl jms = new JavaMailSenderImpl(); JavaMailSenderImpl jms = new JavaMailSenderImpl();
jms.setHost(emailConfig.getHost()); jms.setHost(emailConfig.getHost());
jms.setUsername(emailConfig.getUserName()); jms.setUsername(emailConfig.getUserName());
@ -35,19 +39,19 @@ public class EmailEventListener implements MessageEventListener {
jms.setJavaMailProperties(p); jms.setJavaMailProperties(p);
MimeMessage mimeMessage = jms.createMimeMessage(); MimeMessage mimeMessage = jms.createMimeMessage();
try { try {
String content = getContent(message); String content = message.getFormatContent();
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true); MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
//收件人 //收件人
String[] split = emailConfig.getTo().split(","); String[] split = emailConfig.getTo().split(",");
messageHelper.setTo(split); messageHelper.setTo(split);
//标题 //标题
messageHelper.setSubject(emailConfig.getTitle()); messageHelper.setSubject(content.substring(0, Math.min(20, content.length())));
//内容 //内容
messageHelper.setText(content, true); messageHelper.setText(content, true);
//发件人 //发件人
messageHelper.setFrom(emailConfig.getFrom()); messageHelper.setFrom(emailConfig.getFrom());
jms.send(mimeMessage); jms.send(mimeMessage);
} catch (MessagingException e) { } catch (Exception e) {
log.error("发送邮件失败.", e); log.error("发送邮件失败.", e);
} }
} }

View File

@ -1,8 +1,6 @@
package cc.iotkit.message.listener; package cc.iotkit.message.listener;
import cc.iotkit.message.model.Message; import cc.iotkit.message.event.MessageEvent;
import java.util.Map;
/** /**
* author: * author:
@ -11,14 +9,6 @@ import java.util.Map;
**/ **/
public interface MessageEventListener { public interface MessageEventListener {
void doEvent(Message message); void doEvent(MessageEvent event);
default String getContent(Message message) {
String content = message.getContent();
Map<String, String> param = message.getParam();
for (String key : param.keySet()) {
content = content.replaceAll("${" + key + "}", param.get(key));
}
return content;
}
} }

View File

@ -1,16 +0,0 @@
package cc.iotkit.message.listener;
import cc.iotkit.message.model.Message;
/**
* author:
* date: 2023-05-08 15:09
* description:
**/
public class PhoneMessageEventListener implements MessageEventListener {
@Override
public void doEvent(Message message) {
}
}

View File

@ -1,7 +1,10 @@
package cc.iotkit.message.listener; package cc.iotkit.message.listener;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.message.config.VertxManager; import cc.iotkit.message.config.VertxManager;
import cc.iotkit.message.event.MessageEvent;
import cc.iotkit.message.model.Message; import cc.iotkit.message.model.Message;
import cc.iotkit.message.model.QyWechatConfig;
import cc.iotkit.message.model.QyWechatMessage; import cc.iotkit.message.model.QyWechatMessage;
import io.vertx.ext.web.client.WebClient; import io.vertx.ext.web.client.WebClient;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -17,18 +20,19 @@ import org.springframework.stereotype.Component;
@Component @Component
public class QyWechatEventListener implements MessageEventListener { public class QyWechatEventListener implements MessageEventListener {
private String baseUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s";
@Override @Override
@EventListener(condition = "message.channel()='QyWechat'") @EventListener(classes = MessageEvent.class, condition = "#event.message.channel=='QyWechat'")
public void doEvent(Message message) { public void doEvent(MessageEvent event) {
Message message = event.getMessage();
String channelConfig = message.getChannelConfig();
QyWechatConfig qyWechatConfig = JsonUtils.parse(channelConfig, QyWechatConfig.class);
WebClient client = WebClient.create(VertxManager.INSTANCE.getVertx()); WebClient client = WebClient.create(VertxManager.INSTANCE.getVertx());
String url = String.format(baseUrl, message.getKey());
QyWechatMessage qyWechatMessage = QyWechatMessage.builder() QyWechatMessage qyWechatMessage = QyWechatMessage.builder()
.msgtype("text") .msgtype("text")
.text(QyWechatMessage.MessageContent.builder().content(getContent(message)).build()) .text(QyWechatMessage.MessageContent.builder().content(message.getFormatContent()).build())
.build(); .build();
client.post(url).sendJson(qyWechatMessage) client.post(qyWechatConfig.getQyWechatWebhook()).sendJson(qyWechatMessage)
.onSuccess(response -> log.info("Received response with status code" + response.statusCode())) .onSuccess(response -> log.info("Received response with status code" + response.statusCode()))
.onFailure(err -> log.error("Something went wrong " + err.getMessage())); .onFailure(err -> log.error("Something went wrong " + err.getMessage()));
} }

View File

@ -1,16 +0,0 @@
package cc.iotkit.message.listener;
import cc.iotkit.message.model.Message;
/**
* author:
* date: 2023-05-08 15:09
* description:
**/
public class VoiceEventListener implements MessageEventListener {
@Override
public void doEvent(Message message) {
}
}

View File

@ -0,0 +1,13 @@
package cc.iotkit.message.model;
import lombok.Data;
import java.io.Serializable;
/**
* @author sjg
*/
@Data
public class DingTalkConfig implements Serializable {
private String dingTalkWebhook;
}

View File

@ -1,6 +1,9 @@
package cc.iotkit.message.model; package cc.iotkit.message.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map; import java.util.Map;
@ -10,10 +13,23 @@ import java.util.Map;
* description: * description:
**/ **/
@Data @Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Message { public class Message {
private String key;
private String content; private String content;
private Map<String, String> param; private Map<String, Object> param;
private Long channelId; private Long channelId;
private String channel; private String channel;
private String channelConfig;
private Long alertConfigId;
public String getFormatContent() {
String fmt = content;
for (String key : param.keySet()) {
Object val = param.get(key);
fmt = fmt.replace("${" + key + "}", val == null ? "" : val.toString());
}
return fmt;
}
} }

View File

@ -0,0 +1,13 @@
package cc.iotkit.message.model;
import lombok.Data;
import java.io.Serializable;
/**
* @author sjg
*/
@Data
public class QyWechatConfig implements Serializable {
private String qyWechatWebhook;
}

View File

@ -1,36 +0,0 @@
package cc.iotkit.message.notify;
import cc.iotkit.message.listener.MessageEventListener;
import cc.iotkit.message.model.Message;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* author:
* date: 2023-05-08 15:17
* description:
**/
public class EventManager {
Map<Enum<EventType>, List<MessageEventListener>> listeners = new HashMap<>();
public void subscribe(Enum<EventType> eventType, MessageEventListener listener) {
List<MessageEventListener> users = listeners.get(eventType);
users.add(listener);
}
public void unsubscribe(Enum<EventType> eventType, MessageEventListener listener) {
List<MessageEventListener> users = listeners.get(eventType);
users.remove(listener);
}
public void notify(Enum<EventType> eventType, Message result) {
List<MessageEventListener> users = listeners.get(eventType);
for (MessageEventListener listener : users) {
listener.doEvent(result);
}
}
}

View File

@ -1,10 +0,0 @@
package cc.iotkit.message.notify;
/**
* author:
* date: 2023-05-08 15:21
* description:
**/
public enum EventType {
MQ, Message
}

View File

@ -3,6 +3,7 @@ package cc.iotkit.message.service;
import cc.iotkit.message.event.MessageEvent; import cc.iotkit.message.event.MessageEvent;
import cc.iotkit.message.model.Message; import cc.iotkit.message.model.Message;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -11,12 +12,12 @@ import javax.annotation.Resource;
* date: 2023-05-08 16:02 * date: 2023-05-08 16:02
* description: * description:
**/ **/
@Service
public class MessageService { public class MessageService {
@Resource @Resource
private ApplicationEventPublisher applicationEventPublisher; private ApplicationEventPublisher applicationEventPublisher;
public void sendMessage() { public void sendMessage(Message message) {
Message message = new Message();
applicationEventPublisher.publishEvent(new MessageEvent(message)); applicationEventPublisher.publishEvent(new MessageEvent(message));
} }

View File

@ -104,17 +104,16 @@ public class PluginMainImpl implements IPluginMain, DeviceService {
throw new BizException(ErrCode.PLUGIN_SERVICE_NOT_FOUND); throw new BizException(ErrCode.PLUGIN_SERVICE_NOT_FOUND);
} }
if (!(service.getParams() instanceof Map)) {
throw new BizException(ErrCode.PARAMS_EXCEPTION);
}
Map<String, ?> params = (Map<String, ?>) service.getParams();
IDevice deviceService = deviceServices.get(0); IDevice deviceService = deviceServices.get(0);
String type = service.getType(); String type = service.getType();
String identifier = service.getIdentifier(); String identifier = service.getIdentifier();
ActionResult result = null; ActionResult result = null;
if (ThingService.TYPE_SERVICE.equals(type)) { if (ThingService.TYPE_SERVICE.equals(type)) {
if (!(service.getParams() instanceof Map)) {
throw new BizException(ErrCode.PARAMS_EXCEPTION);
}
Map<String, ?> params = (Map<String, ?>) service.getParams();
//服务调用 //服务调用
ServiceInvoke action = ServiceInvoke.builder() ServiceInvoke action = ServiceInvoke.builder()
.id(service.getMid()) .id(service.getMid())
@ -128,6 +127,10 @@ public class PluginMainImpl implements IPluginMain, DeviceService {
publish(service, result.getCode()); publish(service, result.getCode());
} else if (ThingService.TYPE_PROPERTY.equals(type)) { } else if (ThingService.TYPE_PROPERTY.equals(type)) {
if ("set".equals(identifier)) { if ("set".equals(identifier)) {
if (!(service.getParams() instanceof Map)) {
throw new BizException(ErrCode.PARAMS_EXCEPTION);
}
Map<String, ?> params = (Map<String, ?>) service.getParams();
//属性设置 //属性设置
PropertySet action = PropertySet.builder() PropertySet action = PropertySet.builder()
.id(service.getMid()) .id(service.getMid())
@ -144,7 +147,7 @@ public class PluginMainImpl implements IPluginMain, DeviceService {
.id(service.getMid()) .id(service.getMid())
.productKey(linkPk) .productKey(linkPk)
.deviceName(linkDn) .deviceName(linkDn)
.keys(new ArrayList<>(params.keySet())) .keys((List<String>) service.getParams())
.build(); .build();
//调用插件设备服务接口 //调用插件设备服务接口
result = deviceService.propertyGet(action); result = deviceService.propertyGet(action);

View File

@ -90,7 +90,6 @@ public class ScriptVerticle extends AbstractVerticle {
@Override @Override
public void start() { public void start() {
initTcpServer(); initTcpServer();
log.info("init tcp server failed");
} }
@Override @Override

View File

@ -46,6 +46,11 @@
<artifactId>iot-script-engine</artifactId> <artifactId>iot-script-engine</artifactId>
</dependency> </dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-message-notify</artifactId>
</dependency>
<!--====================第三方库===================--> <!--====================第三方库===================-->
<dependency> <dependency>

View File

@ -30,6 +30,7 @@ public class ScriptService {
private IDeviceInfoData deviceInfoData; private IDeviceInfoData deviceInfoData;
public void setScript(String script) { public void setScript(String script) {
this.script=script;
scriptEngine.setScript(script); scriptEngine.setScript(script);
} }

View File

@ -18,16 +18,19 @@ import lombok.NoArgsConstructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* @author sjg
*/
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Data @Data
public class AlertAction implements Action<AlertService<?>> { public class AlertAction implements Action<AlertService> {
public static final String TYPE = "alarm"; public static final String TYPE = "alert";
private String type; private String type;
private List<AlertService<?>> services; private List<AlertService> services;
@Override @Override
public String getType() { public String getType() {
@ -37,7 +40,7 @@ public class AlertAction implements Action<AlertService<?>> {
@Override @Override
public List<String> execute(ThingModelMessage msg) { public List<String> execute(ThingModelMessage msg) {
List<String> results = new ArrayList<>(); List<String> results = new ArrayList<>();
for (AlertService<?> service : services) { for (AlertService service : services) {
results.add(service.execute(msg)); results.add(service.execute(msg));
} }
return results; return results;

View File

@ -10,8 +10,9 @@
package cc.iotkit.ruleengine.action.alert; package cc.iotkit.ruleengine.action.alert;
import cc.iotkit.common.thing.ThingModelMessage; import cc.iotkit.common.thing.ThingModelMessage;
import cc.iotkit.message.model.Message;
import cc.iotkit.message.service.MessageService;
import cc.iotkit.ruleengine.action.ScriptService; import cc.iotkit.ruleengine.action.ScriptService;
import cc.iotkit.ruleengine.alert.Alerter;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -20,13 +21,17 @@ import lombok.extern.slf4j.Slf4j;
import java.util.Map; import java.util.Map;
/**
* @author sjg
*/
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Slf4j @Slf4j
@Data @Data
public class AlertService<T extends Alerter> extends ScriptService { public class AlertService extends ScriptService {
private String configId;
private T alert; private Message message;
private MessageService messageService;
@SneakyThrows @SneakyThrows
public String execute(ThingModelMessage msg) { public String execute(ThingModelMessage msg) {
@ -37,6 +42,8 @@ public class AlertService<T extends Alerter> extends ScriptService {
log.warn("execScript result is null"); log.warn("execScript result is null");
return "execScript result is null"; return "execScript result is null";
} }
return alert.send(result); message.setParam(result);
messageService.sendMessage(message);
return "ok";
} }
} }

View File

@ -23,6 +23,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
@ -48,11 +49,14 @@ public class RuleDeviceConsumer implements ConsumerHandler<ThingModelMessage>, A
@SneakyThrows @SneakyThrows
@Override @Override
public void handler(ThingModelMessage msg) { public void handler(ThingModelMessage msg) {
log.info("received thing model message:{}", JsonUtils.toJsonString(msg)); log.info("received thing model message:{}", msg);
try { try {
for (DeviceMessageHandler handler : this.handlers) { for (DeviceMessageHandler handler : this.handlers) {
messageHandlerPool.submit(() -> { messageHandlerPool.submit(() -> {
try { try {
if (!(msg.getData() instanceof Map)) {
msg.setData(new HashMap<>());
}
handler.handle(msg); handler.handle(msg);
} catch (Throwable e) { } catch (Throwable e) {
log.error("handler message error", e); log.error("handler message error", e);

View File

@ -13,12 +13,19 @@ import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging; import cc.iotkit.common.api.Paging;
import cc.iotkit.common.utils.JsonUtils; import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.common.utils.StringUtils; import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.data.manager.IDeviceInfoData; import cc.iotkit.data.manager.*;
import cc.iotkit.data.manager.IRuleInfoData; import cc.iotkit.message.model.Message;
import cc.iotkit.message.service.MessageService;
import cc.iotkit.model.alert.AlertConfig;
import cc.iotkit.model.notify.Channel;
import cc.iotkit.model.notify.ChannelConfig;
import cc.iotkit.model.notify.ChannelTemplate;
import cc.iotkit.model.rule.FilterConfig; import cc.iotkit.model.rule.FilterConfig;
import cc.iotkit.model.rule.RuleAction; import cc.iotkit.model.rule.RuleAction;
import cc.iotkit.model.rule.RuleInfo; import cc.iotkit.model.rule.RuleInfo;
import cc.iotkit.ruleengine.action.Action; import cc.iotkit.ruleengine.action.Action;
import cc.iotkit.ruleengine.action.alert.AlertAction;
import cc.iotkit.ruleengine.action.alert.AlertService;
import cc.iotkit.ruleengine.action.device.DeviceAction; import cc.iotkit.ruleengine.action.device.DeviceAction;
import cc.iotkit.ruleengine.action.device.DeviceActionService; import cc.iotkit.ruleengine.action.device.DeviceActionService;
import cc.iotkit.ruleengine.action.http.HttpAction; import cc.iotkit.ruleengine.action.http.HttpAction;
@ -36,6 +43,8 @@ import cc.iotkit.ruleengine.link.LinkFactory;
import cc.iotkit.ruleengine.listener.DeviceListener; import cc.iotkit.ruleengine.listener.DeviceListener;
import cc.iotkit.ruleengine.listener.Listener; import cc.iotkit.ruleengine.listener.Listener;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -44,6 +53,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -68,6 +78,21 @@ public class RuleManager {
@Autowired @Autowired
private DeviceActionService deviceActionService; private DeviceActionService deviceActionService;
@Autowired
private IAlertConfigData alertConfigData;
@Autowired
private IChannelTemplateData channelTemplateData;
@Autowired
private IChannelConfigData channelConfigData;
@Autowired
private IChannelData channelData;
@Autowired
private MessageService messageService;
public RuleManager() { public RuleManager() {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.schedule(this::initRules, 1, TimeUnit.SECONDS); executorService.schedule(this::initRules, 1, TimeUnit.SECONDS);
@ -196,6 +221,46 @@ public class RuleManager {
service.initLink(ruleId); service.initLink(ruleId);
} }
return tcpAction; return tcpAction;
} else if (AlertAction.TYPE.equals(type)) {
List<AlertConfig> alertConfigs = alertConfigData.findAllByCondition(AlertConfig.builder()
.ruleInfoId(ruleId)
.build());
AlertAction alertAction = parse(config, AlertAction.class);
String script = alertAction.getServices().get(0).getScript();
List<AlertService> alertServices = new ArrayList<>();
for (AlertConfig alertConfig : alertConfigs) {
if(alertConfig.getEnable()!=null && !alertConfig.getEnable()){
continue;
}
AlertService service = new AlertService();
service.setScript(script);
service.setDeviceInfoData(deviceInfoData);
service.setMessageService(messageService);
ChannelTemplate channelTemplate = channelTemplateData.findById(alertConfig.getMessageTemplateId());
Long channelConfigId = channelTemplate.getChannelConfigId();
Message message = Message.builder()
.content(channelTemplate.getContent())
.alertConfigId(alertConfig.getId())
.build();
if(channelConfigId!=null) {
ChannelConfig channelConfig = channelConfigData.findById(channelTemplate.getChannelConfigId());
Channel channel = channelData.findById(channelConfig.getChannelId());
message.setChannel(channel.getCode());
message.setChannelId(channel.getId());
message.setChannelConfig(channelConfig.getParam());
}
service.setMessage(message);
alertServices.add(service);
}
alertAction.setServices(alertServices);
return alertAction;
} }
return null; return null;
} }

View File

@ -59,8 +59,8 @@ public class VirtualManager {
private MqProducer<ThingModelMessage> producer; private MqProducer<ThingModelMessage> producer;
public VirtualManager(){ public VirtualManager(){
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); // ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.schedule(this::init, 8, TimeUnit.SECONDS); // executorService.schedule(this::init, 8, TimeUnit.SECONDS);
} }
public void init() { public void init() {