Commit a74459e94e10894ca09fe5e025eb7b78694cacf7

Authored by YunaiV
1 parent 2512f2dd

【代码优化】IoT:实现 IotDeviceEventReportVertxHandler 事件上行

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamService.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceS @@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceS
4 import jakarta.validation.Valid; 4 import jakarta.validation.Valid;
5 5
6 /** 6 /**
7 - * 设备下行 Service 接口 7 + * IoT 设备下行 Service 接口
8 * 8 *
9 * 目的:服务端 -> 插件 -> 设备 9 * 目的:服务端 -> 插件 -> 设备
10 * 10 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java
@@ -35,7 +35,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU @@ -35,7 +35,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
35 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_DOWNSTREAM_FAILED; 35 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_DOWNSTREAM_FAILED;
36 36
37 /** 37 /**
38 - * 设备下行 Service 实现类 38 + * IoT 设备下行 Service 实现类
39 * 39 *
40 * @author 芋道源码 40 * @author 芋道源码
41 */ 41 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamService.java
@@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceS @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceS
7 import jakarta.validation.Valid; 7 import jakarta.validation.Valid;
8 8
9 /** 9 /**
10 - * 设备上行 Service 接口 10 + * IoT 设备上行 Service 接口
11 * 11 *
12 * 目的:设备 -> 插件 -> 服务端 12 * 目的:设备 -> 插件 -> 服务端
13 * 13 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java
@@ -31,7 +31,7 @@ import java.util.Map; @@ -31,7 +31,7 @@ import java.util.Map;
31 import java.util.Objects; 31 import java.util.Objects;
32 32
33 /** 33 /**
34 - * 设备上行 Service 实现类 34 + * IoT 设备上行 Service 实现类
35 * 35 *
36 * @author 芋道源码 36 * @author 芋道源码
37 */ 37 */
@@ -123,11 +123,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { @@ -123,11 +123,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
123 @Override 123 @Override
124 public void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) { 124 public void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) {
125 // 1.1 获得设备 125 // 1.1 获得设备
126 - log.info("[reportDevicePropertyData][上报设备属性: {}]", reportReqDTO); 126 + log.info("[reportDeviceProperty][上报设备属性: {}]", reportReqDTO);
127 IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache( 127 IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache(
128 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); 128 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName());
129 if (device == null) { 129 if (device == null) {
130 - log.error("[reportDevicePropertyData][设备({}/{})不存在]", 130 + log.error("[reportDeviceProperty][设备({}/{})不存在]",
131 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); 131 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName());
132 return; 132 return;
133 } 133 }
@@ -145,11 +145,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { @@ -145,11 +145,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
145 @Override 145 @Override
146 public void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) { 146 public void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) {
147 // 1.1 获得设备 147 // 1.1 获得设备
148 - log.info("[reportDeviceEventData][上报设备事件: {}]", reportReqDTO); 148 + log.info("[reportDeviceEvent][上报设备事件: {}]", reportReqDTO);
149 IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache( 149 IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache(
150 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); 150 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName());
151 if (device == null) { 151 if (device == null) {
152 - log.error("[reportDeviceEventData][设备({}/{})不存在]", 152 + log.error("[reportDeviceEvent][设备({}/{})不存在]",
153 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); 153 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName());
154 return; 154 return;
155 } 155 }
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/upstream/IotDeviceUpstreamServer.java
1 package cn.iocoder.yudao.module.iot.plugin.http.upstream; 1 package cn.iocoder.yudao.module.iot.plugin.http.upstream;
2 2
3 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; 3 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
  4 +import cn.iocoder.yudao.module.iot.plugin.http.upstream.router.IotDeviceEventReportVertxHandler;
4 import cn.iocoder.yudao.module.iot.plugin.http.upstream.router.IotDevicePropertyReportVertxHandler; 5 import cn.iocoder.yudao.module.iot.plugin.http.upstream.router.IotDevicePropertyReportVertxHandler;
5 import io.vertx.core.Vertx; 6 import io.vertx.core.Vertx;
6 import io.vertx.core.http.HttpServer; 7 import io.vertx.core.http.HttpServer;
@@ -32,6 +33,8 @@ public class IotDeviceUpstreamServer { @@ -32,6 +33,8 @@ public class IotDeviceUpstreamServer {
32 router.route().handler(BodyHandler.create()); // 处理 Body 33 router.route().handler(BodyHandler.create()); // 处理 Body
33 router.post(IotDevicePropertyReportVertxHandler.PATH) 34 router.post(IotDevicePropertyReportVertxHandler.PATH)
34 .handler(new IotDevicePropertyReportVertxHandler(deviceUpstreamApi)); 35 .handler(new IotDevicePropertyReportVertxHandler(deviceUpstreamApi));
  36 + router.post(IotDeviceEventReportVertxHandler.PATH)
  37 + .handler(new IotDeviceEventReportVertxHandler(deviceUpstreamApi));
35 // 创建 HttpServer 实例 38 // 创建 HttpServer 实例
36 this.server = vertx.createHttpServer().requestHandler(router); 39 this.server = vertx.createHttpServer().requestHandler(router);
37 } 40 }
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/upstream/router/IotDeviceEventReportVertxHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.plugin.http.upstream.router;
  2 +
  3 +import cn.hutool.core.util.IdUtil;
  4 +import cn.hutool.core.util.ObjUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
  7 +import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEventReportReqDTO;
  8 +import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO;
  9 +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
  10 +import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
  11 +import io.vertx.core.Handler;
  12 +import io.vertx.core.json.JsonObject;
  13 +import io.vertx.ext.web.RoutingContext;
  14 +import lombok.RequiredArgsConstructor;
  15 +import lombok.extern.slf4j.Slf4j;
  16 +
  17 +import java.time.LocalDateTime;
  18 +import java.util.Map;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
  21 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
  22 +
  23 +/**
  24 + * IoT 设备设备上报的 Vert.x Handler
  25 + */
  26 +@RequiredArgsConstructor
  27 +@Slf4j
  28 +public class IotDeviceEventReportVertxHandler implements Handler<RoutingContext> {
  29 +
  30 + public static final String PATH = "/sys/:productKey/:deviceName/thing/event/:identifier/post";
  31 +
  32 + private final IotDeviceUpstreamApi deviceUpstreamApi;
  33 +
  34 + @Override
  35 + @SuppressWarnings("unchecked")
  36 + public void handle(RoutingContext routingContext) {
  37 + // 1. 解析参数
  38 + IotDeviceEventReportReqDTO reportReqDTO;
  39 + try {
  40 + String productKey = routingContext.pathParam("productKey");
  41 + String deviceName = routingContext.pathParam("deviceName");
  42 + String identifier = routingContext.pathParam("identifier");
  43 + JsonObject body = routingContext.body().asJsonObject();
  44 + String id = ObjUtil.defaultIfBlank(body.getString("id"), IdUtil.fastSimpleUUID());
  45 + Map<String, Object> params = (Map<String, Object>) body.getMap().get("params");
  46 + reportReqDTO = ((IotDeviceEventReportReqDTO)
  47 + new IotDeviceEventReportReqDTO().setRequestId(id)
  48 + .setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
  49 + .setProductKey(productKey).setDeviceName(deviceName))
  50 + .setIdentifier(identifier).setParams(params);
  51 + } catch (Exception e) {
  52 + log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
  53 + IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST));
  54 + return;
  55 + }
  56 +
  57 + try {
  58 + // 2. 设备上线
  59 + deviceUpstreamApi.updateDeviceState(((IotDeviceStateUpdateReqDTO)
  60 + new IotDeviceStateUpdateReqDTO().setRequestId(IdUtil.fastSimpleUUID())
  61 + .setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
  62 + .setProductKey(reportReqDTO.getProductKey()).setDeviceName(reportReqDTO.getDeviceName()))
  63 + .setState(IotDeviceStateEnum.ONLINE.getState()));
  64 +
  65 + // 3.1 属性上报
  66 + CommonResult<Boolean> result = deviceUpstreamApi.reportDeviceEvent(reportReqDTO);
  67 + // 3.2 返回结果
  68 + IotPluginCommonUtils.writeJson(routingContext, result);
  69 + } catch (Exception e) {
  70 + log.error("[handle][请求参数({}) 时间上报异常]", reportReqDTO, e);
  71 + IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
  72 + }
  73 + }
  74 +
  75 +}
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/upstream/router/IotDevicePropertyReportVertxHandler.java
@@ -55,6 +55,10 @@ public class IotDevicePropertyReportVertxHandler implements Handler&lt;RoutingConte @@ -55,6 +55,10 @@ public class IotDevicePropertyReportVertxHandler implements Handler&lt;RoutingConte
55 return; 55 return;
56 } 56 }
57 57
  58 + // TODO @芋艿:secret 校验。目前的想法:
  59 + // 方案一:请求的时候,带上 secret 参数,然后进行校验,减少请求的频次。不过可能要看下 mqtt 能不能复用!
  60 + // 方案二:本地有设备信息的缓存,异步刷新。这样可能 mqtt 的校验,和 http 校验都容易适配。
  61 +
58 try { 62 try {
59 // 2. 设备上线 63 // 2. 设备上线
60 deviceUpstreamApi.updateDeviceState(((IotDeviceStateUpdateReqDTO) 64 deviceUpstreamApi.updateDeviceState(((IotDeviceStateUpdateReqDTO)
@@ -68,7 +72,7 @@ public class IotDevicePropertyReportVertxHandler implements Handler&lt;RoutingConte @@ -68,7 +72,7 @@ public class IotDevicePropertyReportVertxHandler implements Handler&lt;RoutingConte
68 // 3.2 返回结果 72 // 3.2 返回结果
69 IotPluginCommonUtils.writeJson(routingContext, result); 73 IotPluginCommonUtils.writeJson(routingContext, result);
70 } catch (Exception e) { 74 } catch (Exception e) {
71 - log.error("[handle][请求参数({}) 属性获取异常]", reportReqDTO, e); 75 + log.error("[handle][请求参数({}) 属性上报异常]", reportReqDTO, e);
72 IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR)); 76 IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
73 } 77 }
74 } 78 }