Commit 5264de077d71f2a24414caf75497d6519cdf9e8f
1 parent
88ef8ba2
【代码评审】IoT:插件体系
Showing
7 changed files
with
21 additions
and
13 deletions
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/pom.xml
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/api/DeviceDataApiClient.java
| @@ -10,6 +10,7 @@ import org.springframework.web.client.RestTemplate; | @@ -10,6 +10,7 @@ import org.springframework.web.client.RestTemplate; | ||
| 10 | 10 | ||
| 11 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 11 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 12 | 12 | ||
| 13 | +// TODO @haohao:类注释,写一下,比较好 | ||
| 13 | @Slf4j | 14 | @Slf4j |
| 14 | public class DeviceDataApiClient implements DeviceDataApi { | 15 | public class DeviceDataApiClient implements DeviceDataApi { |
| 15 | 16 | ||
| @@ -17,32 +18,32 @@ public class DeviceDataApiClient implements DeviceDataApi { | @@ -17,32 +18,32 @@ public class DeviceDataApiClient implements DeviceDataApi { | ||
| 17 | private final String deviceDataUrl; | 18 | private final String deviceDataUrl; |
| 18 | 19 | ||
| 19 | // 可以通过构造器把 RestTemplate 和 baseUrl 注入进来 | 20 | // 可以通过构造器把 RestTemplate 和 baseUrl 注入进来 |
| 21 | + // TODO @haohao:可以用 lombok 简化 | ||
| 20 | public DeviceDataApiClient(RestTemplate restTemplate, String deviceDataUrl) { | 22 | public DeviceDataApiClient(RestTemplate restTemplate, String deviceDataUrl) { |
| 21 | this.restTemplate = restTemplate; | 23 | this.restTemplate = restTemplate; |
| 22 | this.deviceDataUrl = deviceDataUrl; | 24 | this.deviceDataUrl = deviceDataUrl; |
| 23 | } | 25 | } |
| 24 | 26 | ||
| 27 | + // TODO @haohao:返回结果,不用 CommonResult 哈。 | ||
| 25 | @Override | 28 | @Override |
| 26 | public CommonResult<Boolean> updateDeviceStatus(IotDeviceStatusUpdateReqDTO updateReqDTO) { | 29 | public CommonResult<Boolean> updateDeviceStatus(IotDeviceStatusUpdateReqDTO updateReqDTO) { |
| 27 | - // 示例:如果对应的远程地址是 /rpc-api/iot/device-data/update-status | ||
| 28 | String url = deviceDataUrl + "/rpc-api/iot/device-data/update-status"; | 30 | String url = deviceDataUrl + "/rpc-api/iot/device-data/update-status"; |
| 29 | return doPost(url, updateReqDTO, "updateDeviceStatus"); | 31 | return doPost(url, updateReqDTO, "updateDeviceStatus"); |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | @Override | 34 | @Override |
| 33 | public CommonResult<Boolean> reportDeviceEventData(IotDeviceEventReportReqDTO reportReqDTO) { | 35 | public CommonResult<Boolean> reportDeviceEventData(IotDeviceEventReportReqDTO reportReqDTO) { |
| 34 | - // 示例:如果对应的远程地址是 /rpc-api/iot/device-data/report-event | ||
| 35 | String url = deviceDataUrl + "/rpc-api/iot/device-data/report-event"; | 36 | String url = deviceDataUrl + "/rpc-api/iot/device-data/report-event"; |
| 36 | return doPost(url, reportReqDTO, "reportDeviceEventData"); | 37 | return doPost(url, reportReqDTO, "reportDeviceEventData"); |
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | @Override | 40 | @Override |
| 40 | public CommonResult<Boolean> reportDevicePropertyData(IotDevicePropertyReportReqDTO reportReqDTO) { | 41 | public CommonResult<Boolean> reportDevicePropertyData(IotDevicePropertyReportReqDTO reportReqDTO) { |
| 41 | - // 示例:如果对应的远程地址是 /rpc-api/iot/device-data/report-property | ||
| 42 | String url = deviceDataUrl + "/rpc-api/iot/device-data/report-property"; | 42 | String url = deviceDataUrl + "/rpc-api/iot/device-data/report-property"; |
| 43 | return doPost(url, reportReqDTO, "reportDevicePropertyData"); | 43 | return doPost(url, reportReqDTO, "reportDevicePropertyData"); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | + // TODO @haohao:未来可能有 get 类型哈 | ||
| 46 | /** | 47 | /** |
| 47 | * 将与远程服务交互的通用逻辑抽取成一个私有方法 | 48 | * 将与远程服务交互的通用逻辑抽取成一个私有方法 |
| 48 | */ | 49 | */ |
| @@ -51,10 +52,12 @@ public class DeviceDataApiClient implements DeviceDataApi { | @@ -51,10 +52,12 @@ public class DeviceDataApiClient implements DeviceDataApi { | ||
| 51 | try { | 52 | try { |
| 52 | // 这里指定返回类型为 CommonResult<?>,根据后台服务返回的实际结构做调整 | 53 | // 这里指定返回类型为 CommonResult<?>,根据后台服务返回的实际结构做调整 |
| 53 | restTemplate.postForObject(url, requestBody, CommonResult.class); | 54 | restTemplate.postForObject(url, requestBody, CommonResult.class); |
| 55 | + // TODO @haohao:check 结果,是否成功 | ||
| 54 | return success(true); | 56 | return success(true); |
| 55 | } catch (Exception e) { | 57 | } catch (Exception e) { |
| 56 | log.error("[{}] Error sending request to URL: {}", actionName, url, e); | 58 | log.error("[{}] Error sending request to URL: {}", actionName, url, e); |
| 57 | return CommonResult.error(400, "Request error: " + e.getMessage()); | 59 | return CommonResult.error(400, "Request error: " + e.getMessage()); |
| 58 | } | 60 | } |
| 59 | } | 61 | } |
| 62 | + | ||
| 60 | } | 63 | } |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/config/DeviceDataApiInitializer.java
| @@ -8,21 +8,23 @@ import org.springframework.context.annotation.Bean; | @@ -8,21 +8,23 @@ import org.springframework.context.annotation.Bean; | ||
| 8 | import org.springframework.context.annotation.Configuration; | 8 | import org.springframework.context.annotation.Configuration; |
| 9 | import org.springframework.web.client.RestTemplate; | 9 | import org.springframework.web.client.RestTemplate; |
| 10 | 10 | ||
| 11 | +// TODO @haohao:这个最好是 autoconfiguration | ||
| 11 | @Configuration | 12 | @Configuration |
| 12 | public class DeviceDataApiInitializer { | 13 | public class DeviceDataApiInitializer { |
| 13 | 14 | ||
| 15 | + // TODO @haohao:这个要不搞个配置类哈 | ||
| 14 | @Value("${iot.device-data.url}") | 16 | @Value("${iot.device-data.url}") |
| 15 | private String deviceDataUrl; | 17 | private String deviceDataUrl; |
| 16 | 18 | ||
| 17 | @Bean | 19 | @Bean |
| 18 | public RestTemplate restTemplate() { | 20 | public RestTemplate restTemplate() { |
| 19 | - // 如果你有更多的自定义需求,比如连接池、超时时间等,可以在这里设置 | 21 | + // TODO haohao:如果你有更多的自定义需求,比如连接池、超时时间等,可以在这里设置 |
| 20 | return new RestTemplateBuilder().build(); | 22 | return new RestTemplateBuilder().build(); |
| 21 | } | 23 | } |
| 22 | 24 | ||
| 25 | + // TODO @haohao:不存在时,才构建 | ||
| 23 | @Bean | 26 | @Bean |
| 24 | public DeviceDataApi deviceDataApi(RestTemplate restTemplate) { | 27 | public DeviceDataApi deviceDataApi(RestTemplate restTemplate) { |
| 25 | - // 返回我们自定义的 Client 实例 | ||
| 26 | return new DeviceDataApiClient(restTemplate, deviceDataUrl); | 28 | return new DeviceDataApiClient(restTemplate, deviceDataUrl); |
| 27 | } | 29 | } |
| 28 | 30 |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/package-info.java
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/HttpPluginSpringbootApplication.java
| @@ -11,20 +11,20 @@ import org.springframework.context.ConfigurableApplicationContext; | @@ -11,20 +11,20 @@ import org.springframework.context.ConfigurableApplicationContext; | ||
| 11 | * 独立运行入口 | 11 | * 独立运行入口 |
| 12 | */ | 12 | */ |
| 13 | @Slf4j | 13 | @Slf4j |
| 14 | -@SpringBootApplication(scanBasePackages = "cn.iocoder.yudao.module.iot.plugin") | 14 | +@SpringBootApplication(scanBasePackages = "cn.iocoder.yudao.module.iot.plugin") // TODO @haohao:建议不扫描 cn.iocoder.yudao.module.iot.plugin;而是通过自动配置,初始化 common 的 |
| 15 | public class HttpPluginSpringbootApplication { | 15 | public class HttpPluginSpringbootApplication { |
| 16 | 16 | ||
| 17 | public static void main(String[] args) { | 17 | public static void main(String[] args) { |
| 18 | - // 这里可选择 NONE / SERVLET / REACTIVE,看你需求 | ||
| 19 | SpringApplication application = new SpringApplication(HttpPluginSpringbootApplication.class); | 18 | SpringApplication application = new SpringApplication(HttpPluginSpringbootApplication.class); |
| 20 | application.setWebApplicationType(WebApplicationType.NONE); | 19 | application.setWebApplicationType(WebApplicationType.NONE); |
| 21 | - | ||
| 22 | ConfigurableApplicationContext context = application.run(args); | 20 | ConfigurableApplicationContext context = application.run(args); |
| 23 | 21 | ||
| 24 | // 手动获取 VertxService 并启动 | 22 | // 手动获取 VertxService 并启动 |
| 23 | + // TODO @haohao:可以放在 bean 的 init 里么? | ||
| 25 | VertxService vertxService = context.getBean(VertxService.class); | 24 | VertxService vertxService = context.getBean(VertxService.class); |
| 26 | vertxService.startServer(); | 25 | vertxService.startServer(); |
| 27 | 26 | ||
| 28 | log.info("[HttpPluginSpringbootApplication] 独立模式启动完成"); | 27 | log.info("[HttpPluginSpringbootApplication] 独立模式启动完成"); |
| 29 | } | 28 | } |
| 29 | + | ||
| 30 | } | 30 | } |
| 31 | \ No newline at end of file | 31 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/config/HttpVertxPlugin.java
| @@ -21,7 +21,8 @@ public class HttpVertxPlugin extends SpringPlugin { | @@ -21,7 +21,8 @@ public class HttpVertxPlugin extends SpringPlugin { | ||
| 21 | 21 | ||
| 22 | @Override | 22 | @Override |
| 23 | public void start() { | 23 | public void start() { |
| 24 | - log.info("[HttpVertxPlugin] start ..."); | 24 | + // TODO @haohao:这种最好启动中,启动完成,成对打印日志,方便定位问题 |
| 25 | + log.info("[HttpVertxPlugin][start ...]"); | ||
| 25 | 26 | ||
| 26 | // 1. 获取插件上下文 | 27 | // 1. 获取插件上下文 |
| 27 | ApplicationContext pluginContext = getApplicationContext(); | 28 | ApplicationContext pluginContext = getApplicationContext(); |
| @@ -38,7 +39,7 @@ public class HttpVertxPlugin extends SpringPlugin { | @@ -38,7 +39,7 @@ public class HttpVertxPlugin extends SpringPlugin { | ||
| 38 | 39 | ||
| 39 | @Override | 40 | @Override |
| 40 | public void stop() { | 41 | public void stop() { |
| 41 | - log.info("[HttpVertxPlugin] stop ..."); | 42 | + log.info("[HttpVertxPlugin][stop ...]"); |
| 42 | ApplicationContext pluginContext = getApplicationContext(); | 43 | ApplicationContext pluginContext = getApplicationContext(); |
| 43 | if (pluginContext != null) { | 44 | if (pluginContext != null) { |
| 44 | // 停止服务器 | 45 | // 停止服务器 |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/config/HttpVertxPluginConfiguration.java
| @@ -17,6 +17,7 @@ import org.springframework.context.annotation.Configuration; | @@ -17,6 +17,7 @@ import org.springframework.context.annotation.Configuration; | ||
| 17 | @Configuration | 17 | @Configuration |
| 18 | public class HttpVertxPluginConfiguration { | 18 | public class HttpVertxPluginConfiguration { |
| 19 | 19 | ||
| 20 | + // TODO @haohao:这个要不要搞个配置类,更容易维护; | ||
| 20 | /** | 21 | /** |
| 21 | * 可在 application.yml 中配置,默认端口 8092 | 22 | * 可在 application.yml 中配置,默认端口 8092 |
| 22 | */ | 23 | */ |
| @@ -42,15 +43,13 @@ public class HttpVertxPluginConfiguration { | @@ -42,15 +43,13 @@ public class HttpVertxPluginConfiguration { | ||
| 42 | router.route().handler(BodyHandler.create()); | 43 | router.route().handler(BodyHandler.create()); |
| 43 | 44 | ||
| 44 | // 设置路由 | 45 | // 设置路由 |
| 46 | + // TODO @haohao:这个后续,我们是多个 Handler ,还是一个哈? | ||
| 45 | router.post("/sys/:productKey/:deviceName/thing/event/property/post") | 47 | router.post("/sys/:productKey/:deviceName/thing/event/property/post") |
| 46 | .handler(httpVertxHandler); | 48 | .handler(httpVertxHandler); |
| 47 | 49 | ||
| 48 | return router; | 50 | return router; |
| 49 | } | 51 | } |
| 50 | 52 | ||
| 51 | - /** | ||
| 52 | - * 注入你的 Http 处理器 Handler,依赖 DeviceDataApi | ||
| 53 | - */ | ||
| 54 | @Bean | 53 | @Bean |
| 55 | public HttpVertxHandler httpVertxHandler(DeviceDataApi deviceDataApi) { | 54 | public HttpVertxHandler httpVertxHandler(DeviceDataApi deviceDataApi) { |
| 56 | return new HttpVertxHandler(deviceDataApi); | 55 | return new HttpVertxHandler(deviceDataApi); |
| @@ -64,4 +63,5 @@ public class HttpVertxPluginConfiguration { | @@ -64,4 +63,5 @@ public class HttpVertxPluginConfiguration { | ||
| 64 | public VertxService vertxService(Vertx vertx, Router router) { | 63 | public VertxService vertxService(Vertx vertx, Router router) { |
| 65 | return new VertxService(port, vertx, router); | 64 | return new VertxService(port, vertx, router); |
| 66 | } | 65 | } |
| 66 | + | ||
| 67 | } | 67 | } |