Commit 0bdd000226e83ee7b01794030248522b84375616

Authored by YunaiV
1 parent 86e4379e

【代码评审】IoT:mqtt 协议的接入

Showing 13 changed files with 61 additions and 100 deletions
yudao-module-iot/yudao-module-iot-biz/pom.xml
@@ -43,6 +43,11 @@ @@ -43,6 +43,11 @@
43 43
44 <!-- DB 相关 --> 44 <!-- DB 相关 -->
45 <dependency> 45 <dependency>
  46 + <groupId>com.taosdata.jdbc</groupId>
  47 + <artifactId>taos-jdbcdriver</artifactId>
  48 + </dependency>
  49 +
  50 + <dependency>
46 <groupId>cn.iocoder.boot</groupId> 51 <groupId>cn.iocoder.boot</groupId>
47 <artifactId>yudao-spring-boot-starter-mybatis</artifactId> 52 <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
48 </dependency> 53 </dependency>
@@ -107,12 +112,6 @@ @@ -107,12 +112,6 @@
107 <version>24.1.2</version> 112 <version>24.1.2</version>
108 </dependency> 113 </dependency>
109 114
110 - <!-- TDengine 相关依赖 -->  
111 - <dependency>  
112 - <groupId>com.taosdata.jdbc</groupId>  
113 - <artifactId>taos-jdbcdriver</artifactId>  
114 - </dependency>  
115 -  
116 </dependencies> 115 </dependencies>
117 116
118 </project> 117 </project>
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDeviceConfigSetVertxHandler.java
@@ -46,7 +46,6 @@ public class IotDeviceConfigSetVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -46,7 +46,6 @@ public class IotDeviceConfigSetVertxHandler implements Handler&lt;RoutingContext&gt; {
46 .setConfig(config); 46 .setConfig(config);
47 } catch (Exception e) { 47 } catch (Exception e) {
48 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e); 48 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
49 - // 使用IotStandardResponse实体类返回错误  
50 IotStandardResponse errorResponse = IotStandardResponse.error( 49 IotStandardResponse errorResponse = IotStandardResponse.error(
51 null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg()); 50 null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
52 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 51 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
@@ -57,18 +56,16 @@ public class IotDeviceConfigSetVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -57,18 +56,16 @@ public class IotDeviceConfigSetVertxHandler implements Handler&lt;RoutingContext&gt; {
57 try { 56 try {
58 CommonResult<Boolean> result = deviceDownstreamHandler.setDeviceConfig(reqDTO); 57 CommonResult<Boolean> result = deviceDownstreamHandler.setDeviceConfig(reqDTO);
59 58
60 - // 使用IotStandardResponse实体类返回结果 59 + // 3. 响应结果
61 IotStandardResponse response; 60 IotStandardResponse response;
62 if (result.isSuccess()) { 61 if (result.isSuccess()) {
63 response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData()); 62 response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData());
64 } else { 63 } else {
65 - response = IotStandardResponse.error(  
66 - reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg()); 64 + response = IotStandardResponse.error(reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg());
67 } 65 }
68 IotPluginCommonUtils.writeJsonResponse(routingContext, response); 66 IotPluginCommonUtils.writeJsonResponse(routingContext, response);
69 } catch (Exception e) { 67 } catch (Exception e) {
70 log.error("[handle][请求参数({}) 配置设置异常]", reqDTO, e); 68 log.error("[handle][请求参数({}) 配置设置异常]", reqDTO, e);
71 - // 使用IotStandardResponse实体类返回错误  
72 IotStandardResponse errorResponse = IotStandardResponse.error( 69 IotStandardResponse errorResponse = IotStandardResponse.error(
73 reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg()); 70 reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
74 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 71 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDeviceOtaUpgradeVertxHandler.java
@@ -51,7 +51,6 @@ public class IotDeviceOtaUpgradeVertxHandler implements Handler&lt;RoutingContext&gt; @@ -51,7 +51,6 @@ public class IotDeviceOtaUpgradeVertxHandler implements Handler&lt;RoutingContext&gt;
51 .setInformation(information); 51 .setInformation(information);
52 } catch (Exception e) { 52 } catch (Exception e) {
53 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e); 53 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
54 - // 使用IotStandardResponse实体类返回错误  
55 IotStandardResponse errorResponse = IotStandardResponse.error( 54 IotStandardResponse errorResponse = IotStandardResponse.error(
56 null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg()); 55 null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
57 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 56 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
@@ -62,18 +61,16 @@ public class IotDeviceOtaUpgradeVertxHandler implements Handler&lt;RoutingContext&gt; @@ -62,18 +61,16 @@ public class IotDeviceOtaUpgradeVertxHandler implements Handler&lt;RoutingContext&gt;
62 try { 61 try {
63 CommonResult<Boolean> result = deviceDownstreamHandler.upgradeDeviceOta(reqDTO); 62 CommonResult<Boolean> result = deviceDownstreamHandler.upgradeDeviceOta(reqDTO);
64 63
65 - // 使用IotStandardResponse实体类返回结果 64 + // 3. 响应结果
66 IotStandardResponse response; 65 IotStandardResponse response;
67 if (result.isSuccess()) { 66 if (result.isSuccess()) {
68 response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData()); 67 response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData());
69 } else { 68 } else {
70 - response = IotStandardResponse.error(  
71 - reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg()); 69 + response = IotStandardResponse.error(reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg());
72 } 70 }
73 IotPluginCommonUtils.writeJsonResponse(routingContext, response); 71 IotPluginCommonUtils.writeJsonResponse(routingContext, response);
74 } catch (Exception e) { 72 } catch (Exception e) {
75 log.error("[handle][请求参数({}) OTA 升级异常]", reqDTO, e); 73 log.error("[handle][请求参数({}) OTA 升级异常]", reqDTO, e);
76 - // 使用IotStandardResponse实体类返回错误  
77 IotStandardResponse errorResponse = IotStandardResponse.error( 74 IotStandardResponse errorResponse = IotStandardResponse.error(
78 reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg()); 75 reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
79 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 76 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDevicePropertyGetVertxHandler.java
@@ -46,7 +46,6 @@ public class IotDevicePropertyGetVertxHandler implements Handler&lt;RoutingContext&gt; @@ -46,7 +46,6 @@ public class IotDevicePropertyGetVertxHandler implements Handler&lt;RoutingContext&gt;
46 .setIdentifiers(identifiers); 46 .setIdentifiers(identifiers);
47 } catch (Exception e) { 47 } catch (Exception e) {
48 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e); 48 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
49 - // 使用IotStandardResponse实体类返回错误  
50 IotStandardResponse errorResponse = IotStandardResponse.error( 49 IotStandardResponse errorResponse = IotStandardResponse.error(
51 null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg()); 50 null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
52 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 51 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
@@ -57,18 +56,16 @@ public class IotDevicePropertyGetVertxHandler implements Handler&lt;RoutingContext&gt; @@ -57,18 +56,16 @@ public class IotDevicePropertyGetVertxHandler implements Handler&lt;RoutingContext&gt;
57 try { 56 try {
58 CommonResult<Boolean> result = deviceDownstreamHandler.getDeviceProperty(reqDTO); 57 CommonResult<Boolean> result = deviceDownstreamHandler.getDeviceProperty(reqDTO);
59 58
60 - // 使用IotStandardResponse实体类返回结果 59 + // 3. 响应结果
61 IotStandardResponse response; 60 IotStandardResponse response;
62 if (result.isSuccess()) { 61 if (result.isSuccess()) {
63 response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData()); 62 response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData());
64 } else { 63 } else {
65 - response = IotStandardResponse.error(  
66 - reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg()); 64 + response = IotStandardResponse.error(reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg());
67 } 65 }
68 IotPluginCommonUtils.writeJsonResponse(routingContext, response); 66 IotPluginCommonUtils.writeJsonResponse(routingContext, response);
69 } catch (Exception e) { 67 } catch (Exception e) {
70 log.error("[handle][请求参数({}) 属性获取异常]", reqDTO, e); 68 log.error("[handle][请求参数({}) 属性获取异常]", reqDTO, e);
71 - // 使用IotStandardResponse实体类返回错误  
72 IotStandardResponse errorResponse = IotStandardResponse.error( 69 IotStandardResponse errorResponse = IotStandardResponse.error(
73 reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg()); 70 reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
74 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 71 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDevicePropertySetVertxHandler.java
@@ -46,7 +46,6 @@ public class IotDevicePropertySetVertxHandler implements Handler&lt;RoutingContext&gt; @@ -46,7 +46,6 @@ public class IotDevicePropertySetVertxHandler implements Handler&lt;RoutingContext&gt;
46 .setProperties(properties); 46 .setProperties(properties);
47 } catch (Exception e) { 47 } catch (Exception e) {
48 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e); 48 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
49 - // 使用IotStandardResponse实体类返回错误  
50 IotStandardResponse errorResponse = IotStandardResponse.error( 49 IotStandardResponse errorResponse = IotStandardResponse.error(
51 null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg()); 50 null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
52 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 51 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
@@ -57,18 +56,16 @@ public class IotDevicePropertySetVertxHandler implements Handler&lt;RoutingContext&gt; @@ -57,18 +56,16 @@ public class IotDevicePropertySetVertxHandler implements Handler&lt;RoutingContext&gt;
57 try { 56 try {
58 CommonResult<Boolean> result = deviceDownstreamHandler.setDeviceProperty(reqDTO); 57 CommonResult<Boolean> result = deviceDownstreamHandler.setDeviceProperty(reqDTO);
59 58
60 - // 使用IotStandardResponse实体类返回结果 59 + // 3. 响应结果
61 IotStandardResponse response; 60 IotStandardResponse response;
62 if (result.isSuccess()) { 61 if (result.isSuccess()) {
63 response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData()); 62 response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData());
64 } else { 63 } else {
65 - response = IotStandardResponse.error(  
66 - reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg()); 64 + response = IotStandardResponse.error(reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg());
67 } 65 }
68 IotPluginCommonUtils.writeJsonResponse(routingContext, response); 66 IotPluginCommonUtils.writeJsonResponse(routingContext, response);
69 } catch (Exception e) { 67 } catch (Exception e) {
70 log.error("[handle][请求参数({}) 属性设置异常]", reqDTO, e); 68 log.error("[handle][请求参数({}) 属性设置异常]", reqDTO, e);
71 - // 使用IotStandardResponse实体类返回错误  
72 IotStandardResponse errorResponse = IotStandardResponse.error( 69 IotStandardResponse errorResponse = IotStandardResponse.error(
73 reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg()); 70 reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
74 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 71 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDeviceServiceInvokeVertxHandler.java
@@ -48,7 +48,6 @@ public class IotDeviceServiceInvokeVertxHandler implements Handler&lt;RoutingContex @@ -48,7 +48,6 @@ public class IotDeviceServiceInvokeVertxHandler implements Handler&lt;RoutingContex
48 .setIdentifier(identifier).setParams(params); 48 .setIdentifier(identifier).setParams(params);
49 } catch (Exception e) { 49 } catch (Exception e) {
50 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e); 50 log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
51 - // 使用IotStandardResponse实体类返回错误  
52 String method = METHOD_PREFIX + routingContext.pathParam("identifier") + METHOD_SUFFIX; 51 String method = METHOD_PREFIX + routingContext.pathParam("identifier") + METHOD_SUFFIX;
53 IotStandardResponse errorResponse = IotStandardResponse.error( 52 IotStandardResponse errorResponse = IotStandardResponse.error(
54 null, method, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg()); 53 null, method, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
@@ -60,19 +59,17 @@ public class IotDeviceServiceInvokeVertxHandler implements Handler&lt;RoutingContex @@ -60,19 +59,17 @@ public class IotDeviceServiceInvokeVertxHandler implements Handler&lt;RoutingContex
60 try { 59 try {
61 CommonResult<Boolean> result = deviceDownstreamHandler.invokeDeviceService(reqDTO); 60 CommonResult<Boolean> result = deviceDownstreamHandler.invokeDeviceService(reqDTO);
62 61
63 - // 使用IotStandardResponse实体类返回结果 62 + // 3. 响应结果
64 String method = METHOD_PREFIX + reqDTO.getIdentifier() + METHOD_SUFFIX; 63 String method = METHOD_PREFIX + reqDTO.getIdentifier() + METHOD_SUFFIX;
65 IotStandardResponse response; 64 IotStandardResponse response;
66 if (result.isSuccess()) { 65 if (result.isSuccess()) {
67 response = IotStandardResponse.success(reqDTO.getRequestId(), method, result.getData()); 66 response = IotStandardResponse.success(reqDTO.getRequestId(), method, result.getData());
68 } else { 67 } else {
69 - response = IotStandardResponse.error(  
70 - reqDTO.getRequestId(), method, result.getCode(), result.getMsg()); 68 + response = IotStandardResponse.error(reqDTO.getRequestId(), method, result.getCode(), result.getMsg());
71 } 69 }
72 IotPluginCommonUtils.writeJsonResponse(routingContext, response); 70 IotPluginCommonUtils.writeJsonResponse(routingContext, response);
73 } catch (Exception e) { 71 } catch (Exception e) {
74 log.error("[handle][请求参数({}) 服务调用异常]", reqDTO, e); 72 log.error("[handle][请求参数({}) 服务调用异常]", reqDTO, e);
75 - // 使用IotStandardResponse实体类返回错误  
76 String method = METHOD_PREFIX + reqDTO.getIdentifier() + METHOD_SUFFIX; 73 String method = METHOD_PREFIX + reqDTO.getIdentifier() + METHOD_SUFFIX;
77 IotStandardResponse errorResponse = IotStandardResponse.error( 74 IotStandardResponse errorResponse = IotStandardResponse.error(
78 reqDTO.getRequestId(), method, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg()); 75 reqDTO.getRequestId(), method, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/pojo/IotStandardResponse.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.plugin.common.pojo; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.plugin.common.pojo;
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.experimental.Accessors; 4 import lombok.experimental.Accessors;
5 5
  6 +// TODO @芋艿:1)后续考虑,要不要叫 Iot 网关之类的 Response;2)包名 pojo
6 /** 7 /**
7 * IoT 标准协议响应实体类 8 * IoT 标准协议响应实体类
8 * <p> 9 * <p>
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/config/IotEmqxPlugin.java
@@ -10,10 +10,9 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext @@ -10,10 +10,9 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
10 /** 10 /**
11 * EMQX 插件实现类 11 * EMQX 插件实现类
12 * 12 *
13 - * 基于 PF4J 插件框架,实现 EMQX 消息中间件的集成  
14 - * 负责插件的生命周期管理,包括启动、停止和应用上下文的创建 13 + * 基于 PF4J 插件框架,实现 EMQX 消息中间件的集成:负责插件的生命周期管理,包括启动、停止和应用上下文的创建
15 * 14 *
16 - * @author 芋道源码 15 + * @author haohao
17 */ 16 */
18 @Slf4j 17 @Slf4j
19 public class IotEmqxPlugin extends SpringPlugin { 18 public class IotEmqxPlugin extends SpringPlugin {
@@ -26,7 +25,6 @@ public class IotEmqxPlugin extends SpringPlugin { @@ -26,7 +25,6 @@ public class IotEmqxPlugin extends SpringPlugin {
26 public void start() { 25 public void start() {
27 log.info("[EmqxPlugin][EmqxPlugin 插件启动开始...]"); 26 log.info("[EmqxPlugin][EmqxPlugin 插件启动开始...]");
28 try { 27 try {
29 -  
30 log.info("[EmqxPlugin][EmqxPlugin 插件启动成功...]"); 28 log.info("[EmqxPlugin][EmqxPlugin 插件启动成功...]");
31 } catch (Exception e) { 29 } catch (Exception e) {
32 log.error("[EmqxPlugin][EmqxPlugin 插件开启动异常...]", e); 30 log.error("[EmqxPlugin][EmqxPlugin 插件开启动异常...]", e);
@@ -52,6 +50,7 @@ public class IotEmqxPlugin extends SpringPlugin { @@ -52,6 +50,7 @@ public class IotEmqxPlugin extends SpringPlugin {
52 // 继续使用插件自己的 ClassLoader 以加载插件内部的类 50 // 继续使用插件自己的 ClassLoader 以加载插件内部的类
53 pluginContext.setClassLoader(getWrapper().getPluginClassLoader()); 51 pluginContext.setClassLoader(getWrapper().getPluginClassLoader());
54 // 扫描当前插件的自动配置包 52 // 扫描当前插件的自动配置包
  53 + // TODO @芋艿:是不是要配置下包
55 pluginContext.scan("cn.iocoder.yudao.module.iot.plugin.emqx.config"); 54 pluginContext.scan("cn.iocoder.yudao.module.iot.plugin.emqx.config");
56 pluginContext.refresh(); 55 pluginContext.refresh();
57 return pluginContext; 56 return pluginContext;
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/downstream/IotDeviceDownstreamHandlerImpl.java
@@ -17,7 +17,6 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.MQTT_TOPIC_IL @@ -17,7 +17,6 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.MQTT_TOPIC_IL
17 17
18 /** 18 /**
19 * EMQX 插件的 {@link IotDeviceDownstreamHandler} 实现类 19 * EMQX 插件的 {@link IotDeviceDownstreamHandler} 实现类
20 - * <p>  
21 * 20 *
22 * @author 芋道源码 21 * @author 芋道源码
23 */ 22 */
@@ -26,8 +25,7 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle @@ -26,8 +25,7 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle
26 25
27 private static final String SYS_TOPIC_PREFIX = "/sys/"; 26 private static final String SYS_TOPIC_PREFIX = "/sys/";
28 27
29 - // TODO @haohao:讨论,感觉 mqtt 和 http,可以做个相对统一的格式哈。  
30 - // 回复 都使用 Alink 格式,方便后续扩展。 28 + // TODO @haohao:讨论,感觉 mqtt 和 http,可以做个相对统一的格式哈。;回复 都使用 Alink 格式,方便后续扩展。
31 // 设备服务调用 标准 JSON 29 // 设备服务调用 标准 JSON
32 // 请求Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier} 30 // 请求Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}
33 // 响应Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}_reply 31 // 响应Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}_reply
@@ -62,11 +60,8 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle @@ -62,11 +60,8 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle
62 try { 60 try {
63 // 构建请求主题 61 // 构建请求主题
64 String topic = buildServiceTopic(reqDTO.getProductKey(), reqDTO.getDeviceName(), reqDTO.getIdentifier()); 62 String topic = buildServiceTopic(reqDTO.getProductKey(), reqDTO.getDeviceName(), reqDTO.getIdentifier());
65 -  
66 - // 生成请求ID(如果没有提供)  
67 - String requestId = reqDTO.getRequestId() != null ? reqDTO.getRequestId() : generateRequestId();  
68 -  
69 // 构建请求消息 63 // 构建请求消息
  64 + String requestId = reqDTO.getRequestId() != null ? reqDTO.getRequestId() : generateRequestId();
70 JSONObject request = buildServiceRequest(requestId, reqDTO.getIdentifier(), reqDTO.getParams()); 65 JSONObject request = buildServiceRequest(requestId, reqDTO.getIdentifier(), reqDTO.getParams());
71 66
72 // 发送消息 67 // 发送消息
@@ -98,11 +93,8 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle @@ -98,11 +93,8 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle
98 try { 93 try {
99 // 构建请求主题 94 // 构建请求主题
100 String topic = buildPropertySetTopic(reqDTO.getProductKey(), reqDTO.getDeviceName()); 95 String topic = buildPropertySetTopic(reqDTO.getProductKey(), reqDTO.getDeviceName());
101 -  
102 - // 生成请求ID(如果没有提供)  
103 - String requestId = reqDTO.getRequestId() != null ? reqDTO.getRequestId() : generateRequestId();  
104 -  
105 // 构建请求消息 96 // 构建请求消息
  97 + String requestId = reqDTO.getRequestId() != null ? reqDTO.getRequestId() : generateRequestId();
106 JSONObject request = buildPropertySetRequest(requestId, reqDTO.getProperties()); 98 JSONObject request = buildPropertySetRequest(requestId, reqDTO.getProperties());
107 99
108 // 发送消息 100 // 发送消息
@@ -163,7 +155,7 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle @@ -163,7 +155,7 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle
163 } 155 }
164 156
165 /** 157 /**
166 - * 发布MQTT消息 158 + * 发布 MQTT 消息
167 */ 159 */
168 private void publishMessage(String topic, JSONObject payload) { 160 private void publishMessage(String topic, JSONObject payload) {
169 mqttClient.publish( 161 mqttClient.publish(
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/upstream/router/IotDeviceAuthVertxHandler.java
@@ -13,13 +13,12 @@ import lombok.extern.slf4j.Slf4j; @@ -13,13 +13,12 @@ import lombok.extern.slf4j.Slf4j;
13 import java.util.Collections; 13 import java.util.Collections;
14 14
15 /** 15 /**
16 - * IoT Emqx 连接认证的 Vert.x Handler  
17 - * <a href=  
18 - * "https://docs.emqx.com/zh/emqx/latest/access-control/authn/http.html">MQTT  
19 - * HTTP</a> 16 + * IoT EMQX 连接认证的 Vert.x Handler
  17 + *
  18 + * <a href="https://docs.emqx.com/zh/emqx/latest/access-control/authn/http.html">EMQX HTTP</a>
20 * 19 *
21 * 注意:该处理器需要返回特定格式:{"result": "allow"} 或 {"result": "deny"}, 20 * 注意:该处理器需要返回特定格式:{"result": "allow"} 或 {"result": "deny"},
22 - * 以符合 EMQX 认证插件的要求,因此不使用 IotStandardResponse 实体类。 21 + * 以符合 EMQX 认证插件的要求,因此不使用 IotStandardResponse 实体类
23 * 22 *
24 * @author haohao 23 * @author haohao
25 */ 24 */
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/upstream/router/IotDeviceMqttMessageHandler.java
1 package cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router; 1 package cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router;
2 2
  3 +import cn.hutool.core.util.StrUtil;
3 import cn.hutool.json.JSONObject; 4 import cn.hutool.json.JSONObject;
4 import cn.hutool.json.JSONUtil; 5 import cn.hutool.json.JSONUtil;
5 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@@ -21,26 +22,20 @@ import java.util.Map; @@ -21,26 +22,20 @@ import java.util.Map;
21 22
22 /** 23 /**
23 * IoT 设备 MQTT 消息处理器 24 * IoT 设备 MQTT 消息处理器
24 - * <p>  
25 - * 参考:  
26 - * <p>  
27 - * "<a href=  
28 - * "https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services?spm=a2c4g.11186623.0.0.97a72915vRck44#section-g4j-5zg-12b">...</a>"> 25 + *
  26 + * 参考:"<a href="https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services">设备属性、事件、服务</a>">
29 */ 27 */
30 @Slf4j 28 @Slf4j
31 public class IotDeviceMqttMessageHandler { 29 public class IotDeviceMqttMessageHandler {
32 30
33 - // TODO @haohao:讨论,感觉 mqtt 和 http,可以做个相对统一的格式哈。  
34 - // 回复 都使用 Alink 格式,方便后续扩展。 31 + // TODO @haohao:讨论,感觉 mqtt 和 http,可以做个相对统一的格式哈;回复 都使用 Alink 格式,方便后续扩展。
35 // 设备上报属性 标准 JSON 32 // 设备上报属性 标准 JSON
36 // 请求 Topic:/sys/${productKey}/${deviceName}/thing/event/property/post 33 // 请求 Topic:/sys/${productKey}/${deviceName}/thing/event/property/post
37 // 响应 Topic:/sys/${productKey}/${deviceName}/thing/event/property/post_reply 34 // 响应 Topic:/sys/${productKey}/${deviceName}/thing/event/property/post_reply
38 35
39 // 设备上报事件 标准 JSON 36 // 设备上报事件 标准 JSON
40 - // 请求  
41 - // Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post  
42 - // 响应  
43 - // Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply 37 + // 请求 Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post
  38 + // 响应 Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply
44 39
45 private static final String SYS_TOPIC_PREFIX = "/sys/"; 40 private static final String SYS_TOPIC_PREFIX = "/sys/";
46 private static final String PROPERTY_POST_TOPIC = "/thing/event/property/post"; 41 private static final String PROPERTY_POST_TOPIC = "/thing/event/property/post";
@@ -70,7 +65,7 @@ public class IotDeviceMqttMessageHandler { @@ -70,7 +65,7 @@ public class IotDeviceMqttMessageHandler {
70 log.info("[messageHandler][接收到消息][topic: {}][payload: {}]", topic, payload); 65 log.info("[messageHandler][接收到消息][topic: {}][payload: {}]", topic, payload);
71 66
72 try { 67 try {
73 - if (payload == null || payload.isEmpty()) { 68 + if (StrUtil.isEmpty(payload)) {
74 log.warn("[messageHandler][消息内容为空][topic: {}]", topic); 69 log.warn("[messageHandler][消息内容为空][topic: {}]", topic);
75 return; 70 return;
76 } 71 }
@@ -214,27 +209,20 @@ public class IotDeviceMqttMessageHandler { @@ -214,27 +209,20 @@ public class IotDeviceMqttMessageHandler {
214 * @param topic 原始主题 209 * @param topic 原始主题
215 * @param jsonObject 原始消息JSON对象 210 * @param jsonObject 原始消息JSON对象
216 * @param method 响应方法 211 * @param method 响应方法
217 - * @param customData 自定义数据,可为null 212 + * @param customData 自定义数据,可为 null
218 */ 213 */
219 private void sendResponse(String topic, JSONObject jsonObject, String method, Object customData) { 214 private void sendResponse(String topic, JSONObject jsonObject, String method, Object customData) {
220 String replyTopic = topic + REPLY_SUFFIX; 215 String replyTopic = topic + REPLY_SUFFIX;
221 216
222 - // 使用IotStandardResponse实体类构建响应 217 + // 响应结果
223 IotStandardResponse response = IotStandardResponse.success( 218 IotStandardResponse response = IotStandardResponse.success(
224 - jsonObject.getStr("id"),  
225 - method,  
226 - customData);  
227 - 219 + jsonObject.getStr("id"), method, customData);
228 try { 220 try {
229 - mqttClient.publish(replyTopic,  
230 - Buffer.buffer(JsonUtils.toJsonString(response)),  
231 - MqttQoS.AT_LEAST_ONCE,  
232 - false,  
233 - false); 221 + mqttClient.publish(replyTopic, Buffer.buffer(JsonUtils.toJsonString(response)),
  222 + MqttQoS.AT_LEAST_ONCE, false, false);
234 log.info("[sendResponse][发送响应消息成功][topic: {}]", replyTopic); 223 log.info("[sendResponse][发送响应消息成功][topic: {}]", replyTopic);
235 } catch (Exception e) { 224 } catch (Exception e) {
236 - log.error("[sendResponse][发送响应消息失败][topic: {}][response: {}]",  
237 - replyTopic, response, e); 225 + log.error("[sendResponse][发送响应消息失败][topic: {}][response: {}]", replyTopic, response, e);
238 } 226 }
239 } 227 }
240 228
@@ -304,4 +292,5 @@ public class IotDeviceMqttMessageHandler { @@ -304,4 +292,5 @@ public class IotDeviceMqttMessageHandler {
304 292
305 return reportReqDTO; 293 return reportReqDTO;
306 } 294 }
  295 +
307 } 296 }
308 \ No newline at end of file 297 \ No newline at end of file
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/upstream/router/IotDeviceWebhookVertxHandler.java
@@ -16,13 +16,12 @@ import java.time.LocalDateTime; @@ -16,13 +16,12 @@ import java.time.LocalDateTime;
16 import java.util.Collections; 16 import java.util.Collections;
17 17
18 /** 18 /**
19 - * IoT Emqx Webhook 事件处理的 Vert.x Handler 19 + * IoT EMQX Webhook 事件处理的 Vert.x Handler
20 * 20 *
21 - * <a href=  
22 - * "https://docs.emqx.com/zh/emqx/latest/data-integration/webhook.html">EMQXWebhook</a> 21 + * <a href="https://docs.emqx.com/zh/emqx/latest/data-integration/webhook.html">EMQX Webhook</a>
23 * 22 *
24 * 注意:该处理器需要返回特定格式:{"result": "success"} 或 {"result": "error"}, 23 * 注意:该处理器需要返回特定格式:{"result": "success"} 或 {"result": "error"},
25 - * 以符合 EMQX Webhook 插件的要求,因此不使用 IotStandardResponse 实体类。 24 + * 以符合 EMQX Webhook 插件的要求,因此不使用 IotStandardResponse 实体类。
26 * 25 *
27 * @author haohao 26 * @author haohao
28 */ 27 */
@@ -137,7 +136,7 @@ public class IotDeviceWebhookVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -137,7 +136,7 @@ public class IotDeviceWebhookVertxHandler implements Handler&lt;RoutingContext&gt; {
137 * 解析用户名,格式为 deviceName&productKey 136 * 解析用户名,格式为 deviceName&productKey
138 * 137 *
139 * @param username 用户名 138 * @param username 用户名
140 - * @return 解析结果,[0] 为 deviceName,[1] 为productKey,解析失败返回 null 139 + * @return 解析结果,[0] 为 deviceName,[1] 为 productKey,解析失败返回 null
141 */ 140 */
142 private String[] parseUsername(String username) { 141 private String[] parseUsername(String username) {
143 if (StrUtil.isEmpty(username)) { 142 if (StrUtil.isEmpty(username)) {
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/upstream/router/IotDeviceUpstreamVertxHandler.java
@@ -34,9 +34,13 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC @@ -34,9 +34,13 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
34 @Slf4j 34 @Slf4j
35 public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { 35 public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> {
36 36
37 - // 属性上报路径 37 + /**
  38 + * 属性上报路径
  39 + */
38 public static final String PROPERTY_PATH = "/sys/:productKey/:deviceName/thing/event/property/post"; 40 public static final String PROPERTY_PATH = "/sys/:productKey/:deviceName/thing/event/property/post";
39 - // 事件上报路径 41 + /**
  42 + * 事件上报路径
  43 + */
40 public static final String EVENT_PATH = "/sys/:productKey/:deviceName/thing/event/:identifier/post"; 44 public static final String EVENT_PATH = "/sys/:productKey/:deviceName/thing/event/:identifier/post";
41 45
42 private static final String PROPERTY_METHOD = "thing.event.property.post"; 46 private static final String PROPERTY_METHOD = "thing.event.property.post";
@@ -60,7 +64,6 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -60,7 +64,6 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; {
60 // 2. 根据路径模式处理不同类型的请求 64 // 2. 根据路径模式处理不同类型的请求
61 CommonResult<Boolean> result; 65 CommonResult<Boolean> result;
62 String method; 66 String method;
63 -  
64 if (path.matches(".*/thing/event/property/post")) { 67 if (path.matches(".*/thing/event/property/post")) {
65 // 处理属性上报 68 // 处理属性上报
66 IotDevicePropertyReportReqDTO reportReqDTO = parsePropertyReportRequest(productKey, deviceName, requestId, body); 69 IotDevicePropertyReportReqDTO reportReqDTO = parsePropertyReportRequest(productKey, deviceName, requestId, body);
@@ -97,13 +100,13 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -97,13 +100,13 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; {
97 response = IotStandardResponse.error(requestId, method, result.getCode(), result.getMsg()); 100 response = IotStandardResponse.error(requestId, method, result.getCode(), result.getMsg());
98 } 101 }
99 IotPluginCommonUtils.writeJsonResponse(routingContext, response); 102 IotPluginCommonUtils.writeJsonResponse(routingContext, response);
100 -  
101 } catch (Exception e) { 103 } catch (Exception e) {
102 log.error("[handle][处理上行请求异常] path={}", path, e); 104 log.error("[handle][处理上行请求异常] path={}", path, e);
103 -  
104 // 构建错误响应 105 // 构建错误响应
105 - String method = path.contains("/property/") ? PROPERTY_METHOD : EVENT_METHOD_PREFIX + (routingContext.pathParams().containsKey("identifier") ? routingContext.pathParam("identifier") : "unknown") + EVENT_METHOD_SUFFIX;  
106 - 106 + String method = path.contains("/property/") ? PROPERTY_METHOD
  107 + : EVENT_METHOD_PREFIX + (routingContext.pathParams().containsKey("identifier")
  108 + ? routingContext.pathParam("identifier")
  109 + : "unknown") + EVENT_METHOD_SUFFIX;
107 IotStandardResponse errorResponse = IotStandardResponse.error(requestId, method, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg()); 110 IotStandardResponse errorResponse = IotStandardResponse.error(requestId, method, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
108 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse); 111 IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
109 } 112 }
@@ -130,20 +133,16 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -130,20 +133,16 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; {
130 */ 133 */
131 @SuppressWarnings("unchecked") 134 @SuppressWarnings("unchecked")
132 private IotDevicePropertyReportReqDTO parsePropertyReportRequest(String productKey, String deviceName, String requestId, JsonObject body) { 135 private IotDevicePropertyReportReqDTO parsePropertyReportRequest(String productKey, String deviceName, String requestId, JsonObject body) {
133 -  
134 - // 按照标准JSON格式处理属性数据 136 + // 按照标准 JSON 格式处理属性数据
135 Map<String, Object> properties = new HashMap<>(); 137 Map<String, Object> properties = new HashMap<>();
136 -  
137 - // 优先使用params字段,符合标准 138 + // 优先使用 params 字段,符合标准
138 Map<String, Object> params = body.getJsonObject("params") != null ? body.getJsonObject("params").getMap() : null; 139 Map<String, Object> params = body.getJsonObject("params") != null ? body.getJsonObject("params").getMap() : null;
139 -  
140 if (params != null) { 140 if (params != null) {
141 - // 将标准格式的params转换为平台需要的properties格式 141 + // 将标准格式的 params 转换为平台需要的 properties 格式
142 for (Map.Entry<String, Object> entry : params.entrySet()) { 142 for (Map.Entry<String, Object> entry : params.entrySet()) {
143 String key = entry.getKey(); 143 String key = entry.getKey();
144 Object valueObj = entry.getValue(); 144 Object valueObj = entry.getValue();
145 -  
146 - // 如果是复杂结构(包含value和time) 145 + // 如果是复杂结构(包含 value 和 time)
147 if (valueObj instanceof Map) { 146 if (valueObj instanceof Map) {
148 Map<String, Object> valueMap = (Map<String, Object>) valueObj; 147 Map<String, Object> valueMap = (Map<String, Object>) valueObj;
149 properties.put(key, valueMap.getOrDefault("value", valueObj)); 148 properties.put(key, valueMap.getOrDefault("value", valueObj));
@@ -153,6 +152,7 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -153,6 +152,7 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; {
153 } 152 }
154 } 153 }
155 154
  155 + // 构建属性上报请求 DTO
156 return ((IotDevicePropertyReportReqDTO) new IotDevicePropertyReportReqDTO().setRequestId(requestId).setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now()).setProductKey(productKey).setDeviceName(deviceName)).setProperties(properties); 156 return ((IotDevicePropertyReportReqDTO) new IotDevicePropertyReportReqDTO().setRequestId(requestId).setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now()).setProductKey(productKey).setDeviceName(deviceName)).setProperties(properties);
157 } 157 }
158 158
@@ -166,12 +166,9 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -166,12 +166,9 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; {
166 * @param body 请求体 166 * @param body 请求体
167 * @return 事件上报请求DTO 167 * @return 事件上报请求DTO
168 */ 168 */
169 - @SuppressWarnings("unchecked")  
170 private IotDeviceEventReportReqDTO parseEventReportRequest(String productKey, String deviceName, String identifier, String requestId, JsonObject body) { 169 private IotDeviceEventReportReqDTO parseEventReportRequest(String productKey, String deviceName, String identifier, String requestId, JsonObject body) {
171 -  
172 // 按照标准JSON格式处理事件参数 170 // 按照标准JSON格式处理事件参数
173 Map<String, Object> params; 171 Map<String, Object> params;
174 -  
175 // 优先使用params字段,符合标准 172 // 优先使用params字段,符合标准
176 if (body.getJsonObject("params") != null) { 173 if (body.getJsonObject("params") != null) {
177 params = body.getJsonObject("params").getMap(); 174 params = body.getJsonObject("params").getMap();
@@ -180,6 +177,7 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; { @@ -180,6 +177,7 @@ public class IotDeviceUpstreamVertxHandler implements Handler&lt;RoutingContext&gt; {
180 params = new HashMap<>(); 177 params = new HashMap<>();
181 } 178 }
182 179
  180 + // 构建事件上报请求 DTO
183 return ((IotDeviceEventReportReqDTO) new IotDeviceEventReportReqDTO().setRequestId(requestId).setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now()).setProductKey(productKey).setDeviceName(deviceName)).setIdentifier(identifier).setParams(params); 181 return ((IotDeviceEventReportReqDTO) new IotDeviceEventReportReqDTO().setRequestId(requestId).setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now()).setProductKey(productKey).setDeviceName(deviceName)).setIdentifier(identifier).setParams(params);
184 } 182 }
185 } 183 }
186 \ No newline at end of file 184 \ No newline at end of file