@@ -0,0 +1,47 @@ | |||
package com.tuoheng.admin.enums; | |||
import lombok.Getter; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:09 | |||
* @Description: 机场日志告警类型 枚举 | |||
* @Version: 1.0 | |||
*/ | |||
public enum AlarmTypeEnum { | |||
/** | |||
* 常规日志 | |||
*/ | |||
ALARM_LOG("log", "常规日志"), | |||
/** | |||
* 错误日志 | |||
*/ | |||
ALARM_ERROR("error", "错误日志"), | |||
/** | |||
* 紧急日志 | |||
*/ | |||
ALARM_CRITICAL("critical", "紧急日志"), | |||
; | |||
AlarmTypeEnum(String type,String desc) { | |||
this.type = type; | |||
this.desc = desc; | |||
} | |||
/** | |||
* 日志类型 | |||
*/ | |||
@Getter | |||
private String type; | |||
/** | |||
* 描述 | |||
*/ | |||
@Getter | |||
private String desc; | |||
} |
@@ -0,0 +1,15 @@ | |||
package com.tuoheng.admin.mapper; | |||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||
import com.tuoheng.admin.pojo.entity.Alarm; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:31 | |||
* @Description: 机场告警数据 Mapper | |||
* @Version: 1.0 | |||
*/ | |||
public interface AlarmMapper extends BaseMapper<Alarm> { | |||
} |
@@ -0,0 +1,15 @@ | |||
package com.tuoheng.admin.mapper; | |||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||
import com.tuoheng.admin.pojo.entity.Bnconnect; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:12 | |||
* @Description: 机场对接业务系统 Mapper | |||
* @Version: 1.0 | |||
*/ | |||
public interface BnconnectMapper extends BaseMapper<Bnconnect> { | |||
} |
@@ -0,0 +1,61 @@ | |||
package com.tuoheng.admin.pojo.entity; | |||
import com.baomidou.mybatisplus.annotation.TableName; | |||
import com.tuoheng.common.common.BaseEntity; | |||
import lombok.Data; | |||
import lombok.EqualsAndHashCode; | |||
import lombok.experimental.Accessors; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:31 | |||
* @Description: 机场告警数据表 | |||
* @Version: 1.0 | |||
*/ | |||
@Data | |||
@EqualsAndHashCode(callSuper = true) | |||
@Accessors(chain = true) | |||
@TableName("th_alarm") | |||
public class Alarm extends BaseEntity { | |||
private static final long serialVersionUID = 1L; | |||
/** | |||
* 机场ID | |||
*/ | |||
private Integer airportId; | |||
/** | |||
* 控制板ID | |||
*/ | |||
private String edgeId; | |||
/** | |||
* 接收的时间戳 | |||
*/ | |||
private String timestamp; | |||
/** | |||
* 日志类型(log: 常规日志;error: 错误日志; critical: 紧急日志) | |||
*/ | |||
private String type; | |||
/** | |||
* 消息主体 | |||
*/ | |||
private String data; | |||
/** | |||
* 告警消息主体 | |||
*/ | |||
private String critical; | |||
/** | |||
* 处理结果 1 : 已处理, 0: 未处理 | |||
*/ | |||
private Integer result; | |||
public final static Integer HANDLE_AGO = 1;//已处理 | |||
public final static Integer HANDLE_NOT = 0;//未处理 | |||
} |
@@ -0,0 +1,40 @@ | |||
package com.tuoheng.admin.pojo.entity; | |||
import com.baomidou.mybatisplus.annotation.TableName; | |||
import com.tuoheng.common.common.BaseEntity; | |||
import lombok.Data; | |||
import lombok.EqualsAndHashCode; | |||
import lombok.experimental.Accessors; | |||
/** | |||
* <p> | |||
* 机场业务对接表 | |||
* </p> | |||
* | |||
* @author 拓恒 | |||
* @since 2022-11-03 | |||
*/ | |||
@Data | |||
@EqualsAndHashCode(callSuper = true) | |||
@Accessors(chain = true) | |||
@TableName("th_bnconnect") | |||
public class Bnconnect extends BaseEntity { | |||
private static final long serialVersionUID = 1L; | |||
/** | |||
*代码 | |||
*/ | |||
private String code; | |||
//业务系统名称 | |||
private String name; | |||
//业务系统api | |||
private String apiUrl; | |||
private String pushUrl; | |||
private String playUrl; | |||
} |
@@ -0,0 +1,25 @@ | |||
package com.tuoheng.admin.pojo.request; | |||
import com.tuoheng.common.common.BaseQuery; | |||
import lombok.Data; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:12 | |||
* @Description: 机场对接业务系统 query | |||
* @Version: 1.0 | |||
*/ | |||
@Data | |||
public class BnconnectQuery extends BaseQuery { | |||
/** | |||
* 设备编号 | |||
*/ | |||
private String code; | |||
/** | |||
* 设备名称 | |||
*/ | |||
private String name; | |||
} |
@@ -0,0 +1,25 @@ | |||
package com.tuoheng.admin.service.bnconnect; | |||
import com.tuoheng.admin.pojo.entity.Bnconnect; | |||
import com.tuoheng.admin.pojo.request.BnconnectQuery; | |||
import com.tuoheng.common.common.IBaseService; | |||
import com.tuoheng.common.utils.JsonResult; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:12 | |||
* @Description: 机场对接业务系统 服务类 | |||
* @Version: 1.0 | |||
*/ | |||
public interface IBnconnectService extends IBaseService<Bnconnect> { | |||
JsonResult getList(BnconnectQuery query); | |||
Bnconnect selectByCode(String code); | |||
Bnconnect selectByUrl(String url); | |||
JsonResult getListAll(); | |||
} |
@@ -0,0 +1,83 @@ | |||
package com.tuoheng.admin.service.bnconnect.impl; | |||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||
import com.baomidou.mybatisplus.core.metadata.IPage; | |||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||
import com.tuoheng.admin.mapper.BnconnectMapper; | |||
import com.tuoheng.admin.pojo.entity.Bnconnect; | |||
import com.tuoheng.admin.pojo.request.BnconnectQuery; | |||
import com.tuoheng.admin.service.bnconnect.IBnconnectService; | |||
import com.tuoheng.common.common.BaseServiceImpl; | |||
import com.tuoheng.common.utils.JsonResult; | |||
import com.tuoheng.common.utils.StringUtils; | |||
import org.springframework.stereotype.Service; | |||
import javax.annotation.Resource; | |||
import java.util.List; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:12 | |||
* @Description: 机场对接业务系统 服务实现类 | |||
* @Version: 1.0 | |||
*/ | |||
@Service | |||
public class BnconnectServiceImpl extends BaseServiceImpl<BnconnectMapper, Bnconnect> implements IBnconnectService { | |||
@Resource | |||
private BnconnectMapper bnconnectMapper; | |||
@Override | |||
public JsonResult getList(BnconnectQuery bnconnectQuery) { | |||
QueryWrapper wrapper = new QueryWrapper(); | |||
wrapper.eq("mark","1"); | |||
if(StringUtils.isNotEmpty(bnconnectQuery.getCode())) { | |||
wrapper.like("code", bnconnectQuery.getCode()); | |||
} | |||
if(StringUtils.isNotEmpty(bnconnectQuery.getName())) { | |||
wrapper.like("name", bnconnectQuery.getName()); | |||
} | |||
IPage<Bnconnect> page = new Page<>(bnconnectQuery.getPage(), bnconnectQuery.getLimit()); | |||
return JsonResult.success(bnconnectMapper.selectPage(page,wrapper)); | |||
} | |||
@Override | |||
public Bnconnect selectByCode(String code) { | |||
QueryWrapper wrapper = new QueryWrapper(); | |||
wrapper.eq("mark","1"); | |||
wrapper.eq("code",code); | |||
List list =bnconnectMapper.selectList(wrapper); | |||
if (list.size()>0){ | |||
return (Bnconnect) list.get(0); | |||
} | |||
return null; | |||
} | |||
@Override | |||
public Bnconnect selectByUrl(String url) { | |||
QueryWrapper wrapper = new QueryWrapper(); | |||
wrapper.eq("mark","1"); | |||
wrapper.eq("api_url",url); | |||
List list =bnconnectMapper.selectList(wrapper); | |||
if (list.size()>0){ | |||
return (Bnconnect) list.get(0); | |||
} | |||
return null; | |||
} | |||
@Override | |||
public JsonResult getListAll() { | |||
List<Bnconnect> list = list(); | |||
Bnconnect bnconnect = new Bnconnect(); | |||
bnconnect.setCode("airport"); | |||
bnconnect.setName("机场平台"); | |||
list.add(bnconnect); | |||
Bnconnect bnconnect1 = new Bnconnect(); | |||
bnconnect1.setCode("airportTimer"); | |||
bnconnect1.setName("机场平台定时任务"); | |||
list.add(bnconnect1); | |||
return JsonResult.success(list); | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
package com.tuoheng.admin.service.mqttService.consumer.topicHandle; | |||
import org.eclipse.paho.client.mqttv3.MqttMessage; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 10:21 | |||
* @Description: 机场硬件交互顶级服务接口 | |||
* @Version: 1.0 | |||
*/ | |||
public interface ITopicHandleService { | |||
/** | |||
* topic信息,每个topic对应一个处理类 | |||
* | |||
* @return | |||
*/ | |||
String getTopic(); | |||
/** | |||
* 机场topic回调处理 | |||
* @param message MQTT message | |||
* @param edgId 设备ID | |||
*/ | |||
void topicHandle(MqttMessage message, String edgId); | |||
} |
@@ -0,0 +1,161 @@ | |||
package com.tuoheng.admin.service.mqttService.consumer.topicHandle.alarm; | |||
import cn.hutool.core.util.ObjectUtil; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||
import com.tuoheng.admin.enums.AlarmTypeEnum; | |||
import com.tuoheng.admin.enums.MQTTTopicEnum; | |||
import com.tuoheng.admin.enums.ServiceExceptionEnum; | |||
import com.tuoheng.admin.mapper.AirportMapper; | |||
import com.tuoheng.admin.mapper.AlarmMapper; | |||
import com.tuoheng.admin.pojo.entity.Airport; | |||
import com.tuoheng.admin.pojo.entity.Alarm; | |||
import com.tuoheng.admin.pojo.entity.Bnconnect; | |||
import com.tuoheng.admin.service.bnconnect.IBnconnectService; | |||
import com.tuoheng.admin.service.mqttpush.IMqttPushService; | |||
import com.tuoheng.admin.service.mqttService.HttpURLConnectionUtil; | |||
import com.tuoheng.admin.service.mqttService.consumer.topicHandle.ITopicHandleService; | |||
import com.tuoheng.admin.utils.SpringUtil; | |||
import com.tuoheng.common.enums.MarkStatusEnum; | |||
import com.tuoheng.common.utils.JsonResult; | |||
import com.tuoheng.common.utils.StringUtils; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.eclipse.paho.client.mqttv3.MqttMessage; | |||
import org.springframework.stereotype.Service; | |||
import javax.annotation.Resource; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 10:28 | |||
* @Description: 告警记录处理 服务实现类 | |||
* @Version: 1.0 | |||
*/ | |||
@Service | |||
@Slf4j | |||
public class AlarmTopicHandleService implements ITopicHandleService { | |||
@Resource | |||
private AlarmMapper alarmMapper; | |||
/** | |||
* DSP 告警服务URI | |||
*/ | |||
private final static String DSP_ALARM_URI = "/alarm/alarmData"; | |||
/** | |||
* 机场日志记录topic | |||
*/ | |||
private static final String topic = MQTTTopicEnum.TOPIC_POST_WTH.getTopic(); | |||
@Override | |||
public String getTopic() { | |||
return topic; | |||
} | |||
/** | |||
* 告警日志处理 | |||
* | |||
* @param message MQTT message | |||
* @param edgId 设备ID | |||
*/ | |||
@Override | |||
public void topicHandle(MqttMessage message, String edgId) { | |||
/** | |||
* 1、记录告警日志 | |||
* 2、调用DSP接口上报告警数据 | |||
* 3、发送MQTT消息告警已处理 | |||
* 4、DSP调用成功更新告警记录为已处理 | |||
*/ | |||
JSONObject jsonObject = (JSONObject) JSONObject.parse(message.getPayload()); | |||
if (ObjectUtil.isEmpty(jsonObject.get("type")) || ObjectUtil.isEmpty(jsonObject.get("critical"))) { | |||
log.error("告警日志类型或紧急告警内容为空,消息无需处理!"); | |||
return; | |||
} | |||
if (AlarmTypeEnum.ALARM_CRITICAL.getType().equals(jsonObject.get("type").toString())) { | |||
//获取机场信息 | |||
AirportMapper airportMapper = SpringUtil.getBean(AirportMapper.class); | |||
IBnconnectService bnconnectService = SpringUtil.getBean(IBnconnectService.class); | |||
List<Airport> airports = airportMapper.selectList(new LambdaQueryWrapper<Airport>() | |||
.eq(Airport::getMark, MarkStatusEnum.VALID.getCode()) | |||
.eq(Airport::getEdgeId, edgId)); | |||
Bnconnect bnconnect = bnconnectService.selectByCode("alarmDsp"); | |||
String critical = jsonObject.get("critical") == null ? "" : jsonObject.get("critical").toString(); | |||
String data = jsonObject.get("critical") == null ? "" : jsonObject.get("critical").toString(); | |||
String time = jsonObject.get("timestamp") == null ? "0" : jsonObject.get("timestamp").toString(); | |||
IMqttPushService mqttService = SpringUtil.getBean(IMqttPushService.class); | |||
try { | |||
if (airports.size() > 0 && bnconnect != null) { | |||
String airportName = airports.get(0).getName(); | |||
//记录告警日志 | |||
Alarm alarm = new Alarm(); | |||
alarm.setAirportId(airports.get(0).getId()); | |||
alarm.setEdgeId(edgId); | |||
alarm.setCritical(critical); | |||
alarm.setData(data); | |||
alarm.setType(AlarmTypeEnum.ALARM_CRITICAL.getType()); | |||
alarm.setTimestamp(time); | |||
alarm.setResult(Alarm.HANDLE_NOT); | |||
Integer insertResult = alarmMapper.insert(alarm); | |||
if (insertResult <= 0) { | |||
log.error("异常告警数据:{},记录入库异常:", time); | |||
return; | |||
} | |||
log.info("异常告警数据:{},记录入库成功!", time); | |||
//调用DSP,上报异常告警数据 | |||
HttpURLConnectionUtil httpURLConnectionUtil = new HttpURLConnectionUtil(); | |||
//dps请求地址 | |||
String url = bnconnect.getApiUrl() + DSP_ALARM_URI; | |||
//请求参数 | |||
List parm = new ArrayList(); | |||
Map parmMap = new HashMap(); | |||
parmMap.put("platformCode", "001"); | |||
Map parmMapTemplate = new HashMap(); | |||
parmMapTemplate.put("name", airportName); | |||
parmMapTemplate.put("msg", critical); | |||
parmMap.put("alarmData", JSONObject.toJSONString(parmMapTemplate)); | |||
parmMap.put("alarmTemplate", "您好,您所管辖的机场:${name},正在发生告警,告警内容是:${msg},请及时处理!"); | |||
parm.add(parmMap); | |||
String jsonparm = JSONObject.toJSONString(parm); | |||
log.info("请求地址{},请求类型put,请求体{}", url, jsonparm); | |||
String dspResponse = httpURLConnectionUtil.doPut(url, jsonparm); | |||
log.info("请求返回值{}", dspResponse); | |||
if (StringUtils.isEmpty(dspResponse)) { | |||
log.error("异常告警数据上报调用DSP返回结果为空!"); | |||
throw new RuntimeException("异常告警数据上报调用DSP返回结果为空!"); | |||
} else { | |||
JSONObject dspJSObject = JSONObject.parseObject(dspResponse); | |||
if (ObjectUtil.isNotEmpty(dspJSObject) && JsonResult.SUCCESS == dspJSObject.getInteger("code")) { | |||
//发送MQTT消息告警已处理 | |||
mqttService.alarmSend(edgId, Alarm.HANDLE_AGO, Long.parseLong(time)); | |||
log.info("告警数据:{},控制面板ID:{},告警处理已回复", time, edgId); | |||
alarm.setResult(Alarm.HANDLE_AGO); | |||
//更新告警记录已处理 | |||
alarmMapper.updateById(alarm); | |||
} else { | |||
//请求返回失败 | |||
log.error("异常告警数据:{},上报调用DSP异常,返回值:{}", time, dspJSObject); | |||
throw new RuntimeException("异常告警数据上报调用DSP返回结果异常!"); | |||
} | |||
} | |||
} else { | |||
log.error("告警数据:{},控制板ID:{}告警,未查询到机场信息或dsp信息", time, edgId); | |||
throw new RuntimeException("未查询到机场信息或dsp信息!"); | |||
} | |||
}catch (Exception e){ | |||
log.error("告警数据:{},处理异常,通知MQTT消息未处理",time,e); | |||
//发送MQTT消息告警未处理 | |||
mqttService.alarmSend(edgId, Alarm.HANDLE_NOT, Long.parseLong(time)); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
package com.tuoheng.admin.service.mqttpush; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:22 | |||
* @Description: MQTT 消息请求服务类 | |||
* @Version: 1.0 | |||
*/ | |||
public interface IMqttPushService { | |||
/** | |||
* 告警成功反馈 | |||
*/ | |||
void alarmSend(String edgId,int command,long time); | |||
} |
@@ -0,0 +1,33 @@ | |||
package com.tuoheng.admin.service.mqttpush.impl; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.tuoheng.admin.enums.AlarmTypeEnum; | |||
import com.tuoheng.admin.service.mqttpush.IMqttPushService; | |||
import com.tuoheng.admin.service.mqttService.send.MqttProviderConfig; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 11:22 | |||
* @Description: MQTT 消息请求服务实现类 | |||
* @Version: 1.0 | |||
*/ | |||
@Service | |||
@Slf4j | |||
public class MqttPushServiceImpl implements IMqttPushService { | |||
@Autowired | |||
private MqttProviderConfig client; | |||
@Override | |||
public void alarmSend(String edgId, int command,long time) { | |||
JSONObject message = new JSONObject(); | |||
message.put("DeviceID",edgId); | |||
message.put("logID",time); | |||
message.put("type", AlarmTypeEnum.ALARM_CRITICAL.getType()); | |||
message.put("Result",1); | |||
log.info("告警数据:{},控制面板ID:{},告警处理已回复",time,edgId); | |||
client.publish(2,false,"/v1/"+edgId+"/log",message.toJSONString()); | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
package com.tuoheng.common.enums; | |||
import lombok.Getter; | |||
/** | |||
* @Author: 吴彬 | |||
* @CreateTime: 2023-06-12 17:22 | |||
* @Description: 逻辑删除状态 | |||
* @Version: 1.0 | |||
*/ | |||
public enum MarkStatusEnum { | |||
VALID(1,"有效"), | |||
INVALID(0,"失效"); | |||
MarkStatusEnum(int code, String description){ | |||
this.code = code; | |||
this.description = description; | |||
} | |||
@Getter | |||
private int code; | |||
@Getter | |||
private String description; | |||
} |