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,
"title": "告警钉钉配置",
"param": {
"dingTalkWebhook":"xxxxxxxxxxxxxxxx",
"dingTalkSecret":"xxxx"
"dingTalkWebhook":"xxxxxxxxxxxxxxxx"
},
"createAt": 1683816661690
},

View File

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

View File

@ -1,14 +1,11 @@
package cc.iotkit.model.notify;
import cc.iotkit.model.Id;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* author:
* date: 2023-05-11 16:30
@ -26,23 +23,8 @@ public class ChannelConfig implements Id<Long> {
private String title;
private ChannelParam param;
private String param;
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 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;
import cc.iotkit.model.alert.AlertConfig;
import cc.iotkit.model.alert.AlertRecord;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -13,9 +13,8 @@ import javax.persistence.Table;
@Data
@Entity
//@ApiModel(value = "告警记录")
@Table(name = "alert_record")
@AutoMapper(target= AlertConfig.class)
@AutoMapper(target = AlertRecord.class)
public class TbAlertRecord {
@Id

View File

@ -3,11 +3,19 @@ package cc.iotkit.data.service;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.data.dao.AlertRecordRepository;
import cc.iotkit.data.dao.IJPACommData;
import cc.iotkit.data.manager.IAlertRecordData;
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.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.context.annotation.Primary;
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.stereotype.Service;
import static cc.iotkit.data.model.QTbAlertRecord.tbAlertRecord;
@Primary
@Service
public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData<AlertRecord, Long> {
@ -22,6 +32,8 @@ public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData<Alert
@Autowired
private AlertRecordRepository alertRecordRepository;
@Autowired
private JPAQueryFactory jpaQueryFactory;
@Override
public JpaRepository getBaseRepository() {
@ -38,12 +50,19 @@ public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData<Alert
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
public Paging<AlertRecord> selectAlertConfigPage(PageRequest<AlertRecord> request) {
Page<TbAlertRecord> alertRecordPage = alertRecordRepository.findAll(Pageable.ofSize(request.getPageSize())
.withPage(request.getPageNum() - 1));
return new Paging<>(alertRecordPage.getTotalElements(),
MapstructUtils.convert(alertRecordPage.getContent(), AlertRecord.class));
QueryResults<TbAlertRecord> results = jpaQueryFactory.selectFrom(tbAlertRecord).where(genPredicate(request.getData()))
.orderBy(tbAlertRecord.id.desc())
.limit(request.getPageSize())
.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.IJPACommData;
import cc.iotkit.data.manager.IChannelConfigData;
import cc.iotkit.data.model.ChannelConfigMapper;
import cc.iotkit.data.model.TbChannelConfig;
import cc.iotkit.model.notify.ChannelConfig;
import org.springframework.context.annotation.Primary;
@ -15,7 +14,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.stream.Collectors;
/**
* author:
@ -29,9 +27,6 @@ public class ChannelConfigDataImpl implements IChannelConfigData, IJPACommData<C
@Resource
private ChannelConfigRepository channelConfigRepository;
@Resource
private ChannelConfigMapper channelConfigMapper;
@Override
public JpaRepository getBaseRepository() {
return channelConfigRepository;
@ -53,8 +48,6 @@ public class ChannelConfigDataImpl implements IChannelConfigData, IJPACommData<C
return new Paging<>(
tbChannelConfigs.getTotalElements(),
tbChannelConfigs.getContent()
.stream().map(channelConfigMapper::toDto)
.collect(Collectors.toList())
);
).to(ChannelConfig.class);
}
}

View File

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

@ -48,4 +48,14 @@ public class AlertService {
public Paging<AlertRecord> selectAlertRecordPage(PageRequest<AlertRecord> 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>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-core</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>

View File

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

View File

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

View File

@ -1,8 +1,6 @@
package cc.iotkit.message.listener;
import cc.iotkit.message.model.Message;
import java.util.Map;
import cc.iotkit.message.event.MessageEvent;
/**
* author:
@ -11,14 +9,6 @@ import java.util.Map;
**/
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;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.message.config.VertxManager;
import cc.iotkit.message.event.MessageEvent;
import cc.iotkit.message.model.Message;
import cc.iotkit.message.model.QyWechatConfig;
import cc.iotkit.message.model.QyWechatMessage;
import io.vertx.ext.web.client.WebClient;
import lombok.extern.slf4j.Slf4j;
@ -17,18 +20,19 @@ import org.springframework.stereotype.Component;
@Component
public class QyWechatEventListener implements MessageEventListener {
private String baseUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s";
@Override
@EventListener(condition = "message.channel()='QyWechat'")
public void doEvent(Message message) {
@EventListener(classes = MessageEvent.class, condition = "#event.message.channel=='QyWechat'")
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());
String url = String.format(baseUrl, message.getKey());
QyWechatMessage qyWechatMessage = QyWechatMessage.builder()
.msgtype("text")
.text(QyWechatMessage.MessageContent.builder().content(getContent(message)).build())
.text(QyWechatMessage.MessageContent.builder().content(message.getFormatContent()).build())
.build();
client.post(url).sendJson(qyWechatMessage)
client.post(qyWechatConfig.getQyWechatWebhook()).sendJson(qyWechatMessage)
.onSuccess(response -> log.info("Received response with status code" + response.statusCode()))
.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;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
@ -10,10 +13,23 @@ import java.util.Map;
* description:
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Message {
private String key;
private String content;
private Map<String, String> param;
private Map<String, Object> param;
private Long channelId;
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.model.Message;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -11,12 +12,12 @@ import javax.annotation.Resource;
* date: 2023-05-08 16:02
* description:
**/
@Service
public class MessageService {
@Resource
private ApplicationEventPublisher applicationEventPublisher;
public void sendMessage() {
Message message = new Message();
public void sendMessage(Message 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);
}
if (!(service.getParams() instanceof Map)) {
throw new BizException(ErrCode.PARAMS_EXCEPTION);
}
Map<String, ?> params = (Map<String, ?>) service.getParams();
IDevice deviceService = deviceServices.get(0);
String type = service.getType();
String identifier = service.getIdentifier();
ActionResult result = null;
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()
.id(service.getMid())
@ -128,6 +127,10 @@ public class PluginMainImpl implements IPluginMain, DeviceService {
publish(service, result.getCode());
} else if (ThingService.TYPE_PROPERTY.equals(type)) {
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()
.id(service.getMid())
@ -144,7 +147,7 @@ public class PluginMainImpl implements IPluginMain, DeviceService {
.id(service.getMid())
.productKey(linkPk)
.deviceName(linkDn)
.keys(new ArrayList<>(params.keySet()))
.keys((List<String>) service.getParams())
.build();
//调用插件设备服务接口
result = deviceService.propertyGet(action);

View File

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

View File

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

View File

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

View File

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

View File

@ -10,8 +10,9 @@
package cc.iotkit.ruleengine.action.alert;
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.alert.Alerter;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -20,13 +21,17 @@ import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/**
* @author sjg
*/
@EqualsAndHashCode(callSuper = true)
@Slf4j
@Data
public class AlertService<T extends Alerter> extends ScriptService {
private String configId;
public class AlertService extends ScriptService {
private T alert;
private Message message;
private MessageService messageService;
@SneakyThrows
public String execute(ThingModelMessage msg) {
@ -37,6 +42,8 @@ public class AlertService<T extends Alerter> extends ScriptService {
log.warn("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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@ -48,11 +49,14 @@ public class RuleDeviceConsumer implements ConsumerHandler<ThingModelMessage>, A
@SneakyThrows
@Override
public void handler(ThingModelMessage msg) {
log.info("received thing model message:{}", JsonUtils.toJsonString(msg));
log.info("received thing model message:{}", msg);
try {
for (DeviceMessageHandler handler : this.handlers) {
messageHandlerPool.submit(() -> {
try {
if (!(msg.getData() instanceof Map)) {
msg.setData(new HashMap<>());
}
handler.handle(msg);
} catch (Throwable 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.utils.JsonUtils;
import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.data.manager.IRuleInfoData;
import cc.iotkit.data.manager.*;
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.RuleAction;
import cc.iotkit.model.rule.RuleInfo;
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.DeviceActionService;
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.Listener;
import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -44,6 +53,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -68,6 +78,21 @@ public class RuleManager {
@Autowired
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() {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.schedule(this::initRules, 1, TimeUnit.SECONDS);
@ -196,6 +221,46 @@ public class RuleManager {
service.initLink(ruleId);
}
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;
}

View File

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