Commit a74459e94e10894ca09fe5e025eb7b78694cacf7
1 parent
2512f2dd
【代码优化】IoT:实现 IotDeviceEventReportVertxHandler 事件上行
Showing
7 changed files
with
91 additions
and
9 deletions
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<RoutingConte | @@ -55,6 +55,10 @@ public class IotDevicePropertyReportVertxHandler implements Handler<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<RoutingConte | @@ -68,7 +72,7 @@ public class IotDevicePropertyReportVertxHandler implements Handler<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 | } |