From bfc5db85aece671261ecba2e7d70ab8a13e3cce7 Mon Sep 17 00:00:00 2001 From: shikong <919411476@qq.com> Date: Thu, 14 Sep 2023 16:11:41 +0800 Subject: [PATCH] =?UTF-8?q?=E8=99=9A=E6=8B=9F=E8=AE=BE=E5=A4=87=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E5=BD=95=E5=83=8F=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/MessageRequestProcessor.java | 11 ++- .../RecordInfoRequestProcessor.java | 92 +++++++++++++++++++ .../recordinfo/dto/RecordInfoItemDTO.java | 38 ++++++++ .../recordinfo/dto/RecordInfoResponseDTO.java | 38 ++++++++ .../core/sip/response/SipResponseBuilder.java | 7 +- .../mocking/service/device/DeviceService.java | 12 +++ 6 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/RecordInfoRequestProcessor.java create mode 100644 gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/dto/RecordInfoItemDTO.java create mode 100644 gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/dto/RecordInfoResponseDTO.java diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/MessageRequestProcessor.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/MessageRequestProcessor.java index 9f1f4db..4addc77 100644 --- a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/MessageRequestProcessor.java +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/MessageRequestProcessor.java @@ -11,12 +11,14 @@ import cn.skcks.docking.gb28181.core.sip.message.sender.SipMessageSender; import cn.skcks.docking.gb28181.core.sip.utils.SipUtil; import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.catalog.CatalogCmdProcessor; import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.deviceinfo.DeviceInfoRequestProcessor; +import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.RecordInfoRequestProcessor; import cn.skcks.docking.gb28181.mocking.core.sip.message.subscribe.SipSubscribe; import cn.skcks.docking.gb28181.mocking.core.sip.response.SipResponseBuilder; import gov.nist.javax.sip.message.SIPRequest; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import javax.sip.RequestEvent; @@ -38,6 +40,8 @@ public class MessageRequestProcessor implements MessageProcessor { private final CatalogCmdProcessor catalogCmdProcessor; private final DeviceInfoRequestProcessor deviceInfoRequestProcessor; + private final RecordInfoRequestProcessor recordInfoRequestProcessor; + private Response okResponse(SIPRequest request){ return SipResponseBuilder.response(request, Response.OK, "OK"); } @@ -59,12 +63,15 @@ public class MessageRequestProcessor implements MessageProcessor { MessageDTO messageDto = XmlUtils.parse(content, MessageDTO.class, GB28181Constant.CHARSET); log.debug("deviceId:{}, 接收到的消息 => {}", deviceId, messageDto); - if(messageDto.getCmdType().equalsIgnoreCase(CmdType.CATALOG)) { + String cmdType = messageDto.getCmdType(); + if(cmdType.equalsIgnoreCase(CmdType.CATALOG)) { sender.send(senderIp, okResponse(request)); catalogCmdProcessor.process(request, content); - } else if(messageDto.getCmdType().equalsIgnoreCase("DeviceInfo")){ + } else if(cmdType.equalsIgnoreCase("DeviceInfo")){ sender.send(senderIp, okResponse(request)); deviceInfoRequestProcessor.process(request, content); + } else if(StringUtils.equalsIgnoreCase(cmdType,CmdType.RECORD_INFO)){ + recordInfoRequestProcessor.process(request, content); } else { Response response = SipResponseBuilder.response(request, Response.NOT_IMPLEMENTED, ResponseStatus.NOT_IMPLEMENTED.getMessage()); sender.send(senderIp, response); diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/RecordInfoRequestProcessor.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/RecordInfoRequestProcessor.java new file mode 100644 index 0000000..d42cc1d --- /dev/null +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/RecordInfoRequestProcessor.java @@ -0,0 +1,92 @@ +package cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.skcks.docking.gb28181.common.xml.XmlUtils; +import cn.skcks.docking.gb28181.core.sip.message.processor.message.types.recordinfo.query.dto.RecordInfoRequestDTO; +import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.dto.RecordInfoItemDTO; +import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.dto.RecordInfoResponseDTO; +import cn.skcks.docking.gb28181.mocking.core.sip.request.SipRequestBuilder; +import cn.skcks.docking.gb28181.mocking.core.sip.response.SipResponseBuilder; +import cn.skcks.docking.gb28181.mocking.core.sip.sender.SipSender; +import cn.skcks.docking.gb28181.mocking.orm.mybatis.dynamic.model.MockingDevice; +import cn.skcks.docking.gb28181.mocking.service.device.DeviceService; +import gov.nist.javax.sip.message.SIPRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.sip.header.CallIdHeader; +import javax.sip.header.FromHeader; +import javax.sip.message.Response; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +@Slf4j +@RequiredArgsConstructor +@Component +public class RecordInfoRequestProcessor { + private final SipSender sender; + private final DeviceService deviceService; + + public void process(SIPRequest request, byte[] content) { + String senderIp = request.getLocalAddress().getHostAddress(); + String transport = request.getTopmostViaHeader().getTransport(); + RecordInfoRequestDTO recordInfoRequestDTO = XmlUtils.parse(content, RecordInfoRequestDTO.class); + String id = recordInfoRequestDTO.getDeviceId(); + deviceService.getDeviceByGbChannelId(id).ifPresentOrElse((device) -> { + sendRecordInfo(device, recordInfoRequestDTO, request, senderIp, transport); + }, () -> { + deviceService.getDeviceByGbChannelId(id).ifPresentOrElse((device) -> { + sendRecordInfo(device, recordInfoRequestDTO, request, senderIp, transport); + }, () -> { + log.error("未能找到 deviceId: {} 的相关信息", id); + sender.sendResponse(senderIp, transport, notFound(request)); + }); + }); + + } + + private void sendRecordInfo(MockingDevice device, RecordInfoRequestDTO recordInfoRequestDTO, SIPRequest request, String senderIp, String transport) { + sender.sendResponse(senderIp, transport, ok(request)); + Date startTime = recordInfoRequestDTO.getStartTime(); + Date endTime = recordInfoRequestDTO.getEndTime(); + String name = StringUtils.joinWith(" - ", + DateUtil.format(startTime, DatePattern.NORM_DATETIME_FORMATTER), + DateUtil.format(endTime, DatePattern.NORM_DATETIME_FORMATTER)); + + RecordInfoItemDTO recordInfoItemDTO = new RecordInfoItemDTO(); + recordInfoItemDTO.setName(name); + recordInfoItemDTO.setStartTime(startTime); + recordInfoItemDTO.setEndTime(endTime); + recordInfoItemDTO.setSecrecy(recordInfoRequestDTO.getSecrecy()); + recordInfoItemDTO.setDeviceId(device.getGbDeviceId()); + + List recordInfoItemDTOList = Collections.singletonList(recordInfoItemDTO); + RecordInfoResponseDTO recordInfoResponseDTO = new RecordInfoResponseDTO(); + recordInfoResponseDTO.setSn(recordInfoRequestDTO.getSn()); + recordInfoResponseDTO.setDeviceId(device.getGbDeviceId()); + recordInfoResponseDTO.setName(device.getName()); + recordInfoResponseDTO.setSumNum((long) recordInfoItemDTOList.size()); + recordInfoResponseDTO.setRecordList(recordInfoItemDTOList); + + FromHeader fromHeader = request.getFromHeader(); + sender.sendRequest((provider, ip, port) -> { + CallIdHeader callIdHeader = provider.getNewCallId(); + return SipRequestBuilder.createMessageRequest(device, + ip, port, 1, XmlUtils.toXml(recordInfoResponseDTO), fromHeader.getTag(), callIdHeader); + }); + } + + private SipSender.SendResponse ok(SIPRequest request) { + return (provider, ip, port) -> SipResponseBuilder.response(request, Response.OK, + "OK"); + } + + private SipSender.SendResponse notFound(SIPRequest request) { + return (provider, ip, port) -> SipResponseBuilder.response(request, Response.NOT_FOUND, + "Not Found"); + } +} diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/dto/RecordInfoItemDTO.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/dto/RecordInfoItemDTO.java new file mode 100644 index 0000000..595913c --- /dev/null +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/dto/RecordInfoItemDTO.java @@ -0,0 +1,38 @@ +package cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.dto; + +import cn.hutool.core.date.DatePattern; +import cn.skcks.docking.gb28181.core.sip.gb28181.constant.GB28181Constant; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import jakarta.validation.constraints.Min; +import lombok.Data; + +import java.util.Date; + +@Data +@JacksonXmlRootElement(localName = "Item") +public class RecordInfoItemDTO { + /** + * 目标设备的设备编码(必选) + */ + @JacksonXmlProperty(localName = "DeviceID") + private String deviceId; + + private String name; + + private String address; + + @JsonFormat(pattern = DatePattern.UTC_SIMPLE_PATTERN, timezone = GB28181Constant.TIME_ZONE) + private Date startTime; + + @JsonFormat(pattern = DatePattern.UTC_SIMPLE_PATTERN, timezone = GB28181Constant.TIME_ZONE) + private Date endTime; + + @Min(value = 0) + private Integer secrecy = 0; + + private String type = "all"; + + private Long fileSize; +} diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/dto/RecordInfoResponseDTO.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/dto/RecordInfoResponseDTO.java new file mode 100644 index 0000000..4ed325d --- /dev/null +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/message/request/recordinfo/dto/RecordInfoResponseDTO.java @@ -0,0 +1,38 @@ +package cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.dto; + +import cn.skcks.docking.gb28181.core.sip.gb28181.constant.CmdType; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +import java.util.List; + +@Data +@JacksonXmlRootElement(localName = "Response") +public class RecordInfoResponseDTO { + /** + * 命令类型:设备信息查询(必选) + */ + private String cmdType = CmdType.RECORD_INFO; + + /** + * 命令序列号(必选) + */ + @JacksonXmlProperty(localName = "SN") + private String sn; + + /** + * 目标设备的设备编码(必选) + */ + @JacksonXmlProperty(localName = "DeviceID") + private String deviceId; + + private String name; + + private Long sumNum; + + @JacksonXmlElementWrapper(localName = "RecordList") + @JacksonXmlProperty(localName = "Item") + private List recordList; +} diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/response/SipResponseBuilder.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/response/SipResponseBuilder.java index fe86ef0..f10a06d 100644 --- a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/response/SipResponseBuilder.java +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/response/SipResponseBuilder.java @@ -1,13 +1,14 @@ package cn.skcks.docking.gb28181.mocking.core.sip.response; +import cn.skcks.docking.gb28181.core.sip.gb28181.constant.GB28181Constant; import cn.skcks.docking.gb28181.core.sip.message.MessageHelper; import cn.skcks.docking.gb28181.core.sip.utils.SipUtil; +import gov.nist.javax.sip.message.MessageFactoryImpl; import gov.nist.javax.sip.message.SIPRequest; import gov.nist.javax.sip.message.SIPResponse; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import javax.sip.message.MessageFactory; import javax.sip.message.Response; @Slf4j @@ -18,7 +19,9 @@ public class SipResponseBuilder { request.getToHeader().setTag(SipUtil.generateTag()); } - MessageFactory messageFactory = MessageHelper.getSipFactory().createMessageFactory(); + MessageFactoryImpl messageFactory = (MessageFactoryImpl)MessageHelper.getSipFactory().createMessageFactory(); + // 使用 GB28181 默认编码 否则中文将会乱码 + messageFactory.setDefaultContentEncodingCharset(GB28181Constant.CHARSET); SIPResponse response = (SIPResponse)messageFactory.createResponse(status, request); if (message != null) { response.setReasonPhrase(message); diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/service/device/DeviceService.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/service/device/DeviceService.java index 85c0b43..4436596 100644 --- a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/service/device/DeviceService.java +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/service/device/DeviceService.java @@ -47,6 +47,11 @@ public class DeviceService { .and(MockingDeviceDynamicSqlSupport.gbChannelId,isEqualTo(channel))); } + public Optional getDeviceByGbChannelId(String channel){ + return deviceMapper.selectOne(s-> + s.where(MockingDeviceDynamicSqlSupport.gbChannelId,isEqualTo(channel))); + } + /** * 添加设备 * @param device 设备 @@ -78,6 +83,13 @@ public class DeviceService { throw new JsonException(MessageFormat.format("国标编码 {0}, 通道 {1} 已存在" ,gbDeviceId, channel)); } + if(getDeviceByGbChannelId(channel).isPresent()){ + throw new JsonException(MessageFormat.format("通道 {0} 已存在", channel)); + } + + if(getDeviceByGbDeviceId(gbDeviceId).isPresent()){ + throw new JsonException(MessageFormat.format("国标编码 {0} 已存在", gbDeviceId)); + } return deviceMapper.insert(device) > 0; }