yang_shj
1 year ago
14 changed files with 449 additions and 6 deletions
@ -0,0 +1,20 @@ |
|||||||
|
package com.hnac.hzims.alarm.vo; |
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class LevelMessageVo { |
||||||
|
|
||||||
|
@ApiModelProperty(value = "站点编码:用逗号分隔") |
||||||
|
private String projectIds; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "类型") |
||||||
|
private String type; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "开始时间") |
||||||
|
private String startTime; |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package com.hnac.hzims.alarm.vo; |
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class LevelVo { |
||||||
|
|
||||||
|
@ApiModelProperty(value = "告警Id") |
||||||
|
private String id; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "告警时间") |
||||||
|
private String ts; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "设备编码") |
||||||
|
private String devicecode; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "设备名称") |
||||||
|
private String devicename; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "告警内容") |
||||||
|
private String name; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "告警类型") |
||||||
|
private Integer type; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "告警等级") |
||||||
|
private Integer level; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "告警发生时,设备实时数据") |
||||||
|
private String context; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "事件标识") |
||||||
|
private String signage; |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package com.hnac.hzims.alarm.show.service; |
||||||
|
|
||||||
|
/** |
||||||
|
* 等级处理接口 |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
public interface LevelAlarmService { |
||||||
|
|
||||||
|
String message(); |
||||||
|
|
||||||
|
void receive(String message); |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package com.hnac.hzims.alarm.show.service; |
||||||
|
|
||||||
|
import com.hnac.hzims.alarm.entity.AlarmEntity; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
public interface MessageService { |
||||||
|
|
||||||
|
void message(AlarmEntity entity); |
||||||
|
|
||||||
|
void webAppMessage(AlarmEntity entity); |
||||||
|
|
||||||
|
void weChatMessage(AlarmEntity entity); |
||||||
|
} |
@ -0,0 +1,117 @@ |
|||||||
|
package com.hnac.hzims.alarm.show.service.impl; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.alibaba.fastjson.TypeReference; |
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||||
|
import com.hnac.hzims.alarm.constants.AlarmConstants; |
||||||
|
import com.hnac.hzims.alarm.entity.AlarmEntity; |
||||||
|
import com.hnac.hzims.alarm.show.service.AlarmService; |
||||||
|
import com.hnac.hzims.alarm.show.service.LevelAlarmService; |
||||||
|
import com.hnac.hzims.alarm.show.service.MessageService; |
||||||
|
import com.hnac.hzims.alarm.vo.LevelMessageVo; |
||||||
|
import com.hnac.hzims.alarm.vo.LevelVo; |
||||||
|
import com.hnac.hzims.equipment.feign.IEmInfoClient; |
||||||
|
import com.hnac.hzims.equipment.vo.EminfoAndEmParamVo; |
||||||
|
import com.hnac.hzims.operational.station.entity.StationEntity; |
||||||
|
import com.hnac.hzims.operational.station.feign.IStationClient; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springblade.core.tool.api.R; |
||||||
|
import org.springblade.core.tool.utils.CollectionUtil; |
||||||
|
import org.springblade.core.tool.utils.DateUtil; |
||||||
|
import org.springframework.data.redis.core.RedisTemplate; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.CompletableFuture; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* 等级告警实现类 |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Service |
||||||
|
@RequiredArgsConstructor |
||||||
|
public class LevelAlarmServiceImpl implements LevelAlarmService { |
||||||
|
|
||||||
|
private final AlarmService alarmService; |
||||||
|
|
||||||
|
private final MessageService messageService; |
||||||
|
|
||||||
|
private final RedisTemplate redisTemplate; |
||||||
|
|
||||||
|
private final IEmInfoClient deviceClient; |
||||||
|
|
||||||
|
private final IStationClient stationClient; |
||||||
|
|
||||||
|
public final static String device_cache_cofig_final = "hzims:equipment:emInfo:deviceCode.emInfoList"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 发生websocket消息 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String message() { |
||||||
|
StationEntity station = new StationEntity(); |
||||||
|
station.setDataOrigin("0"); |
||||||
|
// 站点
|
||||||
|
R<List<StationEntity>> result = stationClient.list(station); |
||||||
|
if(!result.isSuccess() || CollectionUtil.isEmpty(result.getData())){ |
||||||
|
log.error("level alarm send message station is null"); |
||||||
|
return ""; |
||||||
|
} |
||||||
|
LevelMessageVo message = new LevelMessageVo(); |
||||||
|
message.setProjectIds(result.getData().stream().map(StationEntity::getCode).collect(Collectors.joining(","))); |
||||||
|
message.setType(AlarmConstants.HZ3000_ALARAM.stream().map(String::valueOf).collect(Collectors.joining(","))); |
||||||
|
message.setStartTime(DateUtil.format(new Date(),DateUtil.PATTERN_DATE) + " 00:00:00"); |
||||||
|
return JSONObject.toJSONString(message); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 处理websocket消息 |
||||||
|
* @param message |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void receive(String message) { |
||||||
|
// 对象转换
|
||||||
|
List<LevelVo> levels = JSONObject.parseArray(message,LevelVo.class); |
||||||
|
if(CollectionUtil.isEmpty(levels)){ |
||||||
|
return; |
||||||
|
} |
||||||
|
// 设备
|
||||||
|
List<EminfoAndEmParamVo> devices = JSONObject.parseObject(redisTemplate.opsForValue().get(device_cache_cofig_final).toString(),new TypeReference<List<EminfoAndEmParamVo>>() {}); |
||||||
|
// 查询已经保存等级告警数据
|
||||||
|
List<AlarmEntity> records = alarmService.list(Wrappers.<AlarmEntity>lambdaQuery() |
||||||
|
.ge(AlarmEntity::getAlarmSource,AlarmConstants.LEVEL_ALARM) |
||||||
|
.in(AlarmEntity::getAlarmId,levels.stream().map(LevelVo::getId).collect(Collectors.toList())) |
||||||
|
); |
||||||
|
// 遍历等级告警数据
|
||||||
|
levels.stream().filter(o-> CollectionUtil.isEmpty(records) || !records.stream().map(AlarmEntity::getAlarmId).collect(Collectors.toList()).contains(o.getId())). |
||||||
|
forEach(level->{ |
||||||
|
AlarmEntity entity = new AlarmEntity(); |
||||||
|
entity.setAlarmSource(AlarmConstants.LEVEL_ALARM); |
||||||
|
entity.setAlarmId(level.getId()); |
||||||
|
entity.setAlarmTime(DateUtil.parse(level.getTs(), "yyyy-MM-dd HH:mm:ss.s")); |
||||||
|
entity.setAlarmType(level.getType()); |
||||||
|
entity.setRealId(level.getSignage()); |
||||||
|
entity.setAlarmContext(level.getName()); |
||||||
|
entity.setDeviceCode(level.getDevicecode()); |
||||||
|
entity.setDeviceName(level.getDevicename()); |
||||||
|
entity.setAlarmLevel(level.getLevel()); |
||||||
|
List<EminfoAndEmParamVo> ems = devices.stream().filter(o->level.getDevicecode().equals(o.getEmCode())).collect(Collectors.toList()); |
||||||
|
if(CollectionUtil.isNotEmpty(ems)){ |
||||||
|
entity.setStationId(ems.get(0).getStationCode()); |
||||||
|
entity.setDeviceName(ems.get(0).getStationName()); |
||||||
|
} |
||||||
|
this.alarmService.save(entity); |
||||||
|
// 短信
|
||||||
|
CompletableFuture.runAsync(() -> this.messageService.message(entity)); |
||||||
|
// web/app消息推送
|
||||||
|
CompletableFuture.runAsync(() -> this.messageService.webAppMessage(entity)); |
||||||
|
// 微信公众号推送
|
||||||
|
CompletableFuture.runAsync(() -> this.messageService.weChatMessage(entity)); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
package com.hnac.hzims.alarm.show.service.impl; |
||||||
|
|
||||||
|
import com.hnac.hzims.alarm.entity.AlarmEntity; |
||||||
|
import com.hnac.hzims.alarm.show.service.MessageService; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
/** |
||||||
|
* 消息推送实现类 |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Service |
||||||
|
@RequiredArgsConstructor |
||||||
|
public class MessageServiceImpl implements MessageService { |
||||||
|
|
||||||
|
/** |
||||||
|
* 短信推送 |
||||||
|
* @param entity : 告警对象 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void message(AlarmEntity entity) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* web/app消息推送 |
||||||
|
* @param entity : 告警对象 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void webAppMessage(AlarmEntity entity) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 微信公众号消息推送 |
||||||
|
* @param entity |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void weChatMessage(AlarmEntity entity) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
package com.hnac.hzims.alarm.ws.level; |
||||||
|
|
||||||
|
import com.hnac.hzims.alarm.show.service.LevelAlarmService; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springblade.core.tool.utils.ObjectUtil; |
||||||
|
import org.springblade.core.tool.utils.StringUtil; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling; |
||||||
|
import org.springframework.scheduling.annotation.Scheduled; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import java.net.URI; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Component |
||||||
|
@EnableScheduling |
||||||
|
public class LevelAlarmRegular { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private LevelAlarmService levelService; |
||||||
|
|
||||||
|
private LevelAlarmWebSocket socket; |
||||||
|
|
||||||
|
@Value("${hzims.level.ws-url}") |
||||||
|
private String level_wss_url; |
||||||
|
|
||||||
|
// 两分钟进行一次检查链接是否存活,不存活了重新建立链接
|
||||||
|
@Scheduled(cron = "0 0/2 * * * ?") |
||||||
|
private void regular(){ |
||||||
|
// 检查链接存活状态
|
||||||
|
if(ObjectUtil.isEmpty(socket) || !socket.isOpen()){ |
||||||
|
log.error("level websocket survival check : {}","死亡"); |
||||||
|
this.createSocket(); |
||||||
|
if(ObjectUtil.isNotEmpty(socket) && socket.isOpen()){ |
||||||
|
String message = levelService.message(); |
||||||
|
if(!StringUtil.isEmpty(message)){ |
||||||
|
socket.send(message); |
||||||
|
} |
||||||
|
} |
||||||
|
log.error("level websocket survival check : {}","重新建立链接"); |
||||||
|
}else{ |
||||||
|
log.error("level websocket survival check : {}","存活"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 创建websocket链接
|
||||||
|
private void createSocket() { |
||||||
|
try{ |
||||||
|
socket = new LevelAlarmWebSocket(new URI(level_wss_url)); |
||||||
|
socket.connectBlocking(); |
||||||
|
}catch (Exception e){ |
||||||
|
log.error("level create error : {}",e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,125 @@ |
|||||||
|
package com.hnac.hzims.alarm.ws.level; |
||||||
|
|
||||||
|
import com.hnac.hzims.alarm.show.service.LevelAlarmService; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.java_websocket.client.WebSocketClient; |
||||||
|
import org.java_websocket.handshake.ServerHandshake; |
||||||
|
import org.springblade.core.tool.utils.SpringUtil; |
||||||
|
import org.springblade.core.tool.utils.StringUtil; |
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext; |
||||||
|
import javax.net.ssl.TrustManager; |
||||||
|
import javax.net.ssl.X509TrustManager; |
||||||
|
import java.net.Socket; |
||||||
|
import java.net.URI; |
||||||
|
import java.security.SecureRandom; |
||||||
|
import java.security.cert.X509Certificate; |
||||||
|
import java.util.Optional; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
public class LevelAlarmWebSocket extends WebSocketClient { |
||||||
|
|
||||||
|
|
||||||
|
private final LevelAlarmService levelService; |
||||||
|
|
||||||
|
/** |
||||||
|
* 构造等级告警websocket |
||||||
|
* @param uri |
||||||
|
*/ |
||||||
|
public LevelAlarmWebSocket(URI uri) { |
||||||
|
super(uri); |
||||||
|
levelService = SpringUtil.getBean(LevelAlarmService.class); |
||||||
|
connection(this); |
||||||
|
} |
||||||
|
|
||||||
|
// 链接到服务器回调接口
|
||||||
|
@Override |
||||||
|
public void onOpen(ServerHandshake handshakedata) { |
||||||
|
log.error("systemAlarm websocket open"); |
||||||
|
} |
||||||
|
|
||||||
|
// 接收到服务器消息回调接口
|
||||||
|
@Override |
||||||
|
public void onMessage(String message) { |
||||||
|
if(StringUtil.isEmpty(message)){ |
||||||
|
log.error("level alarm on message is null"); |
||||||
|
}else{ |
||||||
|
// 等级告警数据处理
|
||||||
|
levelService.receive(message); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 与服务器链接中断回调接口
|
||||||
|
@Override |
||||||
|
public void onClose(int code, String reason, boolean remote) { |
||||||
|
log.error("level alarm websocket close"); |
||||||
|
} |
||||||
|
|
||||||
|
// 与服务器通讯异常触发
|
||||||
|
@Override |
||||||
|
public void onError(Exception e) { |
||||||
|
log.error("level alarm websocket error : {}",e.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 建立链接 |
||||||
|
* @param webSocket |
||||||
|
*/ |
||||||
|
private void connection(LevelAlarmWebSocket webSocket) { |
||||||
|
SSLContext context = init(); |
||||||
|
if(Optional.ofNullable(context).isPresent()){ |
||||||
|
Socket socket = create(context); |
||||||
|
if(Optional.ofNullable(socket).isPresent()){ |
||||||
|
webSocket.setSocket(socket); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建Socket |
||||||
|
* @param context |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private Socket create(SSLContext context) { |
||||||
|
Socket socket = null; |
||||||
|
try{ |
||||||
|
socket = context.getSocketFactory().createSocket(); |
||||||
|
}catch (Exception e){ |
||||||
|
log.error("level alarm socket create error : {}",e.getMessage()); |
||||||
|
} |
||||||
|
return socket; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 协议初始化 |
||||||
|
* @return SSLContext |
||||||
|
*/ |
||||||
|
private SSLContext init() { |
||||||
|
SSLContext SSL = null; |
||||||
|
try{ |
||||||
|
SSL = SSLContext.getInstance("TLS"); |
||||||
|
SSL.init(null, new TrustManager[]{new X509TrustManager() { |
||||||
|
@Override |
||||||
|
public void checkClientTrusted(X509Certificate[] chain, |
||||||
|
String authType) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void checkServerTrusted(X509Certificate[] chain, String authType) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public X509Certificate[] getAcceptedIssuers() { |
||||||
|
return new X509Certificate[0]; |
||||||
|
} |
||||||
|
}}, new SecureRandom()); |
||||||
|
}catch (Exception e){ |
||||||
|
log.error("level alarm SSL init error : {}",e.getMessage()); |
||||||
|
} |
||||||
|
return SSL; |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue