【代码评审】IoT:插件体系

This commit is contained in:
YunaiV 2025-01-25 11:26:10 +08:00
parent 88ef8ba2e3
commit 5264de077d
7 changed files with 21 additions and 13 deletions

View File

@ -13,6 +13,7 @@
<name>${project.artifactId}</name> <name>${project.artifactId}</name>
<description> <description>
<!-- TODO @芋艿:注释 -->
物联网 插件 模块 - 通用功能 物联网 插件 模块 - 通用功能
</description> </description>

View File

@ -10,6 +10,7 @@ import org.springframework.web.client.RestTemplate;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
// TODO @haohao类注释写一下比较好
@Slf4j @Slf4j
public class DeviceDataApiClient implements DeviceDataApi { public class DeviceDataApiClient implements DeviceDataApi {
@ -17,32 +18,32 @@ public class DeviceDataApiClient implements DeviceDataApi {
private final String deviceDataUrl; private final String deviceDataUrl;
// 可以通过构造器把 RestTemplate baseUrl 注入进来 // 可以通过构造器把 RestTemplate baseUrl 注入进来
// TODO @haohao可以用 lombok 简化
public DeviceDataApiClient(RestTemplate restTemplate, String deviceDataUrl) { public DeviceDataApiClient(RestTemplate restTemplate, String deviceDataUrl) {
this.restTemplate = restTemplate; this.restTemplate = restTemplate;
this.deviceDataUrl = deviceDataUrl; this.deviceDataUrl = deviceDataUrl;
} }
// TODO @haohao返回结果不用 CommonResult
@Override @Override
public CommonResult<Boolean> updateDeviceStatus(IotDeviceStatusUpdateReqDTO updateReqDTO) { public CommonResult<Boolean> updateDeviceStatus(IotDeviceStatusUpdateReqDTO updateReqDTO) {
// 示例如果对应的远程地址是 /rpc-api/iot/device-data/update-status
String url = deviceDataUrl + "/rpc-api/iot/device-data/update-status"; String url = deviceDataUrl + "/rpc-api/iot/device-data/update-status";
return doPost(url, updateReqDTO, "updateDeviceStatus"); return doPost(url, updateReqDTO, "updateDeviceStatus");
} }
@Override @Override
public CommonResult<Boolean> reportDeviceEventData(IotDeviceEventReportReqDTO reportReqDTO) { public CommonResult<Boolean> reportDeviceEventData(IotDeviceEventReportReqDTO reportReqDTO) {
// 示例如果对应的远程地址是 /rpc-api/iot/device-data/report-event
String url = deviceDataUrl + "/rpc-api/iot/device-data/report-event"; String url = deviceDataUrl + "/rpc-api/iot/device-data/report-event";
return doPost(url, reportReqDTO, "reportDeviceEventData"); return doPost(url, reportReqDTO, "reportDeviceEventData");
} }
@Override @Override
public CommonResult<Boolean> reportDevicePropertyData(IotDevicePropertyReportReqDTO reportReqDTO) { public CommonResult<Boolean> reportDevicePropertyData(IotDevicePropertyReportReqDTO reportReqDTO) {
// 示例如果对应的远程地址是 /rpc-api/iot/device-data/report-property
String url = deviceDataUrl + "/rpc-api/iot/device-data/report-property"; String url = deviceDataUrl + "/rpc-api/iot/device-data/report-property";
return doPost(url, reportReqDTO, "reportDevicePropertyData"); return doPost(url, reportReqDTO, "reportDevicePropertyData");
} }
// TODO @haohao未来可能有 get 类型哈
/** /**
* 将与远程服务交互的通用逻辑抽取成一个私有方法 * 将与远程服务交互的通用逻辑抽取成一个私有方法
*/ */
@ -51,10 +52,12 @@ public class DeviceDataApiClient implements DeviceDataApi {
try { try {
// 这里指定返回类型为 CommonResult<?>根据后台服务返回的实际结构做调整 // 这里指定返回类型为 CommonResult<?>根据后台服务返回的实际结构做调整
restTemplate.postForObject(url, requestBody, CommonResult.class); restTemplate.postForObject(url, requestBody, CommonResult.class);
// TODO @haohaocheck 结果是否成功
return success(true); return success(true);
} catch (Exception e) { } catch (Exception e) {
log.error("[{}] Error sending request to URL: {}", actionName, url, e); log.error("[{}] Error sending request to URL: {}", actionName, url, e);
return CommonResult.error(400, "Request error: " + e.getMessage()); return CommonResult.error(400, "Request error: " + e.getMessage());
} }
} }
} }

View File

@ -8,21 +8,23 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
// TODO @haohao这个最好是 autoconfiguration
@Configuration @Configuration
public class DeviceDataApiInitializer { public class DeviceDataApiInitializer {
// TODO @haohao这个要不搞个配置类哈
@Value("${iot.device-data.url}") @Value("${iot.device-data.url}")
private String deviceDataUrl; private String deviceDataUrl;
@Bean @Bean
public RestTemplate restTemplate() { public RestTemplate restTemplate() {
// 如果你有更多的自定义需求比如连接池超时时间等可以在这里设置 // TODO haohao如果你有更多的自定义需求比如连接池超时时间等可以在这里设置
return new RestTemplateBuilder().build(); return new RestTemplateBuilder().build();
} }
// TODO @haohao不存在时才构建
@Bean @Bean
public DeviceDataApi deviceDataApi(RestTemplate restTemplate) { public DeviceDataApi deviceDataApi(RestTemplate restTemplate) {
// 返回我们自定义的 Client 实例
return new DeviceDataApiClient(restTemplate, deviceDataUrl); return new DeviceDataApiClient(restTemplate, deviceDataUrl);
} }

View File

@ -1 +1,2 @@
// TODO @芋艿注释
package cn.iocoder.yudao.module.iot.plugin.common; package cn.iocoder.yudao.module.iot.plugin.common;

View File

@ -11,20 +11,20 @@ import org.springframework.context.ConfigurableApplicationContext;
* 独立运行入口 * 独立运行入口
*/ */
@Slf4j @Slf4j
@SpringBootApplication(scanBasePackages = "cn.iocoder.yudao.module.iot.plugin") @SpringBootApplication(scanBasePackages = "cn.iocoder.yudao.module.iot.plugin") // TODO @haohao建议不扫描 cn.iocoder.yudao.module.iot.plugin而是通过自动配置初始化 common
public class HttpPluginSpringbootApplication { public class HttpPluginSpringbootApplication {
public static void main(String[] args) { public static void main(String[] args) {
// 这里可选择 NONE / SERVLET / REACTIVE看你需求
SpringApplication application = new SpringApplication(HttpPluginSpringbootApplication.class); SpringApplication application = new SpringApplication(HttpPluginSpringbootApplication.class);
application.setWebApplicationType(WebApplicationType.NONE); application.setWebApplicationType(WebApplicationType.NONE);
ConfigurableApplicationContext context = application.run(args); ConfigurableApplicationContext context = application.run(args);
// 手动获取 VertxService 并启动 // 手动获取 VertxService 并启动
// TODO @haohao可以放在 bean init 里么
VertxService vertxService = context.getBean(VertxService.class); VertxService vertxService = context.getBean(VertxService.class);
vertxService.startServer(); vertxService.startServer();
log.info("[HttpPluginSpringbootApplication] 独立模式启动完成"); log.info("[HttpPluginSpringbootApplication] 独立模式启动完成");
} }
} }

View File

@ -21,7 +21,8 @@ public class HttpVertxPlugin extends SpringPlugin {
@Override @Override
public void start() { public void start() {
log.info("[HttpVertxPlugin] start ..."); // TODO @haohao这种最好启动中启动完成成对打印日志方便定位问题
log.info("[HttpVertxPlugin][start ...]");
// 1. 获取插件上下文 // 1. 获取插件上下文
ApplicationContext pluginContext = getApplicationContext(); ApplicationContext pluginContext = getApplicationContext();
@ -38,7 +39,7 @@ public class HttpVertxPlugin extends SpringPlugin {
@Override @Override
public void stop() { public void stop() {
log.info("[HttpVertxPlugin] stop ..."); log.info("[HttpVertxPlugin][stop ...]");
ApplicationContext pluginContext = getApplicationContext(); ApplicationContext pluginContext = getApplicationContext();
if (pluginContext != null) { if (pluginContext != null) {
// 停止服务器 // 停止服务器

View File

@ -17,6 +17,7 @@ import org.springframework.context.annotation.Configuration;
@Configuration @Configuration
public class HttpVertxPluginConfiguration { public class HttpVertxPluginConfiguration {
// TODO @haohao这个要不要搞个配置类更容易维护
/** /**
* 可在 application.yml 中配置默认端口 8092 * 可在 application.yml 中配置默认端口 8092
*/ */
@ -42,15 +43,13 @@ public class HttpVertxPluginConfiguration {
router.route().handler(BodyHandler.create()); router.route().handler(BodyHandler.create());
// 设置路由 // 设置路由
// TODO @haohao这个后续我们是多个 Handler 还是一个哈
router.post("/sys/:productKey/:deviceName/thing/event/property/post") router.post("/sys/:productKey/:deviceName/thing/event/property/post")
.handler(httpVertxHandler); .handler(httpVertxHandler);
return router; return router;
} }
/**
* 注入你的 Http 处理器 Handler依赖 DeviceDataApi
*/
@Bean @Bean
public HttpVertxHandler httpVertxHandler(DeviceDataApi deviceDataApi) { public HttpVertxHandler httpVertxHandler(DeviceDataApi deviceDataApi) {
return new HttpVertxHandler(deviceDataApi); return new HttpVertxHandler(deviceDataApi);
@ -64,4 +63,5 @@ public class HttpVertxPluginConfiguration {
public VertxService vertxService(Vertx vertx, Router router) { public VertxService vertxService(Vertx vertx, Router router) {
return new VertxService(port, vertx, router); return new VertxService(port, vertx, router);
} }
} }