|
@@ -0,0 +1,391 @@
|
|
|
+package org.jeecg.modules.api.imf.msg;
|
|
|
+
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
|
+import com.fasterxml.jackson.databind.MapperFeature;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import com.fasterxml.jackson.databind.json.JsonMapper;
|
|
|
+import com.google.common.base.Strings;
|
|
|
+import lombok.SneakyThrows;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.jeecg.boot.starter.rabbitmq.client.RabbitMqClient;
|
|
|
+import org.jeecg.common.util.RedisUtil;
|
|
|
+import org.jeecg.common.util.SpringContextUtils;
|
|
|
+import org.jeecg.modules.admin_aircraft_position.entity.AdminAircraftPosition;
|
|
|
+import org.jeecg.modules.admin_aircraft_position.service.IAdminAircraftPositionService;
|
|
|
+import org.jeecg.modules.admin_dfdl_list.entity.AdminDfdlList;
|
|
|
+import org.jeecg.modules.admin_dfdl_list.service.IAdminDfdlListService;
|
|
|
+import org.jeecg.modules.admin_dfdl_mq.service.AdminDfdlMqService;
|
|
|
+import org.jeecg.modules.utils.ConversionUtil;
|
|
|
+import org.springframework.context.ApplicationContext;
|
|
|
+import org.w3c.dom.Document;
|
|
|
+import org.xml.sax.InputSource;
|
|
|
+import org.xml.sax.SAXException;
|
|
|
+
|
|
|
+import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
+import javax.xml.parsers.ParserConfigurationException;
|
|
|
+import javax.xml.xpath.XPath;
|
|
|
+import javax.xml.xpath.XPathConstants;
|
|
|
+import javax.xml.xpath.XPathFactory;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.StringReader;
|
|
|
+import java.text.ParseException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author 王葆权
|
|
|
+ * @Title:
|
|
|
+ * @Package org.jeecg.modules.api.imf.msg
|
|
|
+ * @Description:
|
|
|
+ * @date 2023/7/18 10:07
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+abstract class ImfMsgAbstract<T extends ImfMsgType> implements ImfMsg {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 存储mq中发送的dfdl原消息
|
|
|
+ */
|
|
|
+ private AdminDfdlMqService adminDfdlMqService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 机位表
|
|
|
+ */
|
|
|
+ private IAdminAircraftPositionService adminAircraftPositionService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * redis工具
|
|
|
+ */
|
|
|
+ private RedisUtil redisUtil;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * rabbitMq客户端
|
|
|
+ */
|
|
|
+ private RabbitMqClient rabbitMqClient;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计划表
|
|
|
+ */
|
|
|
+ private IAdminDfdlListService adminDfdlListService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否转发处理消息事件
|
|
|
+ */
|
|
|
+ private boolean msgHandlerEvent;
|
|
|
+
|
|
|
+ // 消息头的正则
|
|
|
+ public static final String HEAD_REG = "<META>(.*?)</META>";
|
|
|
+ // 消息体的正则
|
|
|
+ public static final String CONTENT_REG = "<DFLT>(.*?)</DFLT>";
|
|
|
+ // 到达时间的正则
|
|
|
+ public static final String STND_REGEX = "<STND>(.*?)</STND>";
|
|
|
+
|
|
|
+ //xml字符串
|
|
|
+ private String xmlStr;
|
|
|
+
|
|
|
+ //文档字符串
|
|
|
+ private Document xmlDocument;
|
|
|
+
|
|
|
+ // 消息类型枚举
|
|
|
+ private T msgType;
|
|
|
+
|
|
|
+ public ImfMsgAbstract(String xmlStr, T msgType) {
|
|
|
+ setXmlStr(xmlStr);
|
|
|
+ setXmlDocument(xmlStrToDoc(xmlStr));
|
|
|
+ setMsgType(msgType);
|
|
|
+ adminDfdlMqService = SpringContextUtils.getBean(AdminDfdlMqService.class);
|
|
|
+ adminAircraftPositionService = SpringContextUtils.getBean(IAdminAircraftPositionService.class);
|
|
|
+ redisUtil = SpringContextUtils.getBean(RedisUtil.class);
|
|
|
+ rabbitMqClient = SpringContextUtils.getBean(RabbitMqClient.class);
|
|
|
+ adminDfdlListService = SpringContextUtils.getBean(IAdminDfdlListService.class);
|
|
|
+ ApplicationContext applicationContext = SpringContextUtils.getApplicationContext();
|
|
|
+ msgHandlerEvent = applicationContext.getEnvironment().getProperty("airport.mq.msgHandlerEvent", boolean.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void process() {
|
|
|
+ log.info("【{}】开始处理", getTypeDescription());
|
|
|
+ handle();
|
|
|
+ log.info("【{}】结束处理", getTypeDescription());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public synchronized Document xmlStrToDoc(String xml) {
|
|
|
+ Document doc = null;
|
|
|
+ try {
|
|
|
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
|
+ doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
|
|
|
+ } catch (SAXException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ } catch (ParserConfigurationException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ return doc;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public synchronized XPath getXpath() {
|
|
|
+ XPathFactory xPathfactory = XPathFactory.newInstance();
|
|
|
+ XPath xpath = xPathfactory.newXPath();
|
|
|
+ return xpath;
|
|
|
+ }
|
|
|
+
|
|
|
+ @SneakyThrows
|
|
|
+ @Override
|
|
|
+ public String getStrVal(String expression) {
|
|
|
+ XPath xpath = getXpath();
|
|
|
+ Object evaluate = xpath.evaluate(expression, getXmlDocument(), XPathConstants.STRING);
|
|
|
+ return String.valueOf(evaluate);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String xmlToJson(String xml) {
|
|
|
+ return ConversionUtil.xmlToJson(xml);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取类型名称
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public String getTypeName() {
|
|
|
+ return getMsgType().getName();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取消息头
|
|
|
+ *
|
|
|
+ * @return json
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public String getHeader() {
|
|
|
+ return ConversionUtil.xmlToJson(regStr(HEAD_REG, getXmlStr()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ImfMsgHeader getHeaderObject() {
|
|
|
+ JsonMapper jsonMapper = new JsonMapper();
|
|
|
+ ImfMsgHeader imfMsgHeader = null;
|
|
|
+ try {
|
|
|
+ imfMsgHeader = jsonMapper.readValue(getHeader(), ImfMsgHeader.class);
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ return imfMsgHeader;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取消息体
|
|
|
+ * 这里不做转换 需要自定义处理
|
|
|
+ *
|
|
|
+ * @return xml
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public String getContent() {
|
|
|
+ return regStr(CONTENT_REG, getXmlStr());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用正则表达式获取字符串
|
|
|
+ *
|
|
|
+ * @param regStr 表达式
|
|
|
+ * @param str 要查找的字符串
|
|
|
+ * @return 找到的字符串,找不到返回null
|
|
|
+ */
|
|
|
+ public String regStr(String regStr, String str) {
|
|
|
+ Pattern pattern = Pattern.compile(regStr);
|
|
|
+ Matcher matcher = pattern.matcher(str);
|
|
|
+ if (matcher.find()) {
|
|
|
+ return matcher.group();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取类型描述
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String getTypeDescription() {
|
|
|
+ return getMsgType().getDescription();
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getXmlStr() {
|
|
|
+ return xmlStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setXmlStr(String xmlStr) {
|
|
|
+ this.xmlStr = xmlStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Document getXmlDocument() {
|
|
|
+ return xmlDocument;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setXmlDocument(Document xmlDocument) {
|
|
|
+ this.xmlDocument = xmlDocument;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T getMsgType() {
|
|
|
+ return msgType;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setMsgType(T msgType) {
|
|
|
+ this.msgType = msgType;
|
|
|
+ }
|
|
|
+
|
|
|
+ public AdminDfdlMqService getAdminDfdlMqService() {
|
|
|
+ return adminDfdlMqService;
|
|
|
+ }
|
|
|
+
|
|
|
+ public IAdminAircraftPositionService getAdminAircraftPositionService() {
|
|
|
+ return adminAircraftPositionService;
|
|
|
+ }
|
|
|
+
|
|
|
+ public IAdminDfdlListService getAdminDfdlListService() {
|
|
|
+ return adminDfdlListService;
|
|
|
+ }
|
|
|
+
|
|
|
+ public RedisUtil getRedisUtil() {
|
|
|
+ return redisUtil;
|
|
|
+ }
|
|
|
+
|
|
|
+ public RabbitMqClient getRabbitMqClient() {
|
|
|
+ return rabbitMqClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean isMsgHandlerEvent() {
|
|
|
+ return msgHandlerEvent;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ObjectMapper getObjectMapper() {
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ //忽略大小写
|
|
|
+ objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
|
|
|
+ //忽略多余内容
|
|
|
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
|
+ return objectMapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将字符串转换为时间
|
|
|
+ * 目前消息中时间格式都是 yyyyMMddHHmmss
|
|
|
+ *
|
|
|
+ * @param str
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Date strToDate(String str) {
|
|
|
+
|
|
|
+ if (!Strings.isNullOrEmpty(str)) {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
|
|
|
+ //预计开始占用时间
|
|
|
+ try {
|
|
|
+ return sdf.parse(str);
|
|
|
+ } catch (ParseException e) {
|
|
|
+ log.error("日期转换出错");
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将计划中的信息复制给机位中的消息
|
|
|
+ *
|
|
|
+ * @param adminDfdlList 计划
|
|
|
+ * @param airPosition 机位
|
|
|
+ */
|
|
|
+ void adminDfdlCopyToAirPosition(AdminDfdlList adminDfdlList, AdminAircraftPosition airPosition) {
|
|
|
+ airPosition.setFlightSole(String.valueOf(adminDfdlList.getFlid()));
|
|
|
+ airPosition.setFlightAfid(String.valueOf(adminDfdlList.getAfid()));
|
|
|
+ airPosition.setFlightNum(adminDfdlList.getAwcd() + "-" + adminDfdlList.getFlno());
|
|
|
+ airPosition.setAircraftNum(adminDfdlList.getCfno());
|
|
|
+ airPosition.setEstr(adminDfdlList.getEstr());
|
|
|
+ airPosition.setEend(adminDfdlList.getEend());
|
|
|
+ airPosition.setRstr(adminDfdlList.getRstr());
|
|
|
+ airPosition.setRend(adminDfdlList.getRend());
|
|
|
+ }
|
|
|
+
|
|
|
+ void setStlsDate(ObjectMapper objectMapper, String nodeStr, AdminDfdlList adminDfdlList) {
|
|
|
+ String gateStr = regStr(STND_REGEX, nodeStr);
|
|
|
+ if (Strings.isNullOrEmpty(gateStr)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String gateJson = ConversionUtil.xmlToJson(gateStr);
|
|
|
+ Map map = null;
|
|
|
+ try {
|
|
|
+ map = objectMapper.readValue(gateJson, Map.class);
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ Object estr = map.get("ESTR");
|
|
|
+ if (estr != null) {
|
|
|
+ adminDfdlList.setEstr(strToDate(String.valueOf(estr)));
|
|
|
+ }
|
|
|
+ Object eend = map.get("EEND");
|
|
|
+ if (eend != null) {
|
|
|
+ adminDfdlList.setEend(strToDate(String.valueOf(eend)));
|
|
|
+ }
|
|
|
+
|
|
|
+ Object rstr = map.get("RSTR");
|
|
|
+ if (rstr != null) {
|
|
|
+ adminDfdlList.setRstr(strToDate(String.valueOf(rstr)));
|
|
|
+ }
|
|
|
+ Object rend = map.get("REND");
|
|
|
+ if (rend != null) {
|
|
|
+ adminDfdlList.setRend(strToDate(String.valueOf(rend)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void setStlsDate(AdminDfdlList adminDfdlList){
|
|
|
+ setStlsDate(getObjectMapper(),getXmlStr(),adminDfdlList);
|
|
|
+ }
|
|
|
+
|
|
|
+ Map getStlsDateMap(ObjectMapper objectMapper, String nodeStr) {
|
|
|
+ String gateStr = regStr(STND_REGEX, nodeStr);
|
|
|
+ String gateJson = ConversionUtil.xmlToJson(gateStr);
|
|
|
+ Map map = null;
|
|
|
+ try {
|
|
|
+ map = objectMapper.readValue(gateJson, Map.class);
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ Map getStlsDateMap(String nodeStr) {
|
|
|
+ return getStlsDateMap(getObjectMapper(), nodeStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新计划
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ boolean updateAdminDfdl(AdminDfdlList adminDfdlList) {
|
|
|
+ if (adminDfdlList == null || adminDfdlList.getFlid() == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ log.info("更新计划flid:{}",adminDfdlList.getFlid());
|
|
|
+ boolean b = getAdminDfdlListService().updateById(adminDfdlList);
|
|
|
+ if (b) {
|
|
|
+ //更新缓存
|
|
|
+ String key = ImfMsgType.DFDL.getRedisKey() + adminDfdlList.getFlid();
|
|
|
+ if (getRedisUtil().hasKey(key)) {
|
|
|
+ try {
|
|
|
+ AdminDfdlList byId = getAdminDfdlListService().getById(adminDfdlList.getFlid());
|
|
|
+ getRedisUtil().set(key, getObjectMapper().writeValueAsString(byId));
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+}
|