【代码新增】IoT:优化 plugins 相关的代码,包拆成分 upstream、downstream、config 三个,职责更明确
This commit is contained in:
parent
2d18e218c7
commit
4a251b19c4
|
@ -1,9 +1,9 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.common.config;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.core.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.core.downstream.IotDeviceDownstreamServer;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.core.upstream.IotDeviceUpstreamClient;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamServer;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.upstream.IotDeviceUpstreamClient;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
|
@ -12,14 +12,13 @@ import org.springframework.web.client.RestTemplate;
|
|||
|
||||
import java.time.Duration;
|
||||
|
||||
// TODO @芋艿:配置类的名字
|
||||
/**
|
||||
* 设备数据 API 初始化器
|
||||
* IoT 插件的通用自动配置类
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@AutoConfiguration
|
||||
public class YudaoDeviceDataApiAutoConfiguration {
|
||||
public class IotPluginCommonAutoConfiguration {
|
||||
|
||||
// TODO @haohao:这个要不搞个配置类哈
|
||||
@Value("${iot.device-data.url}")
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.common.core.downstream;
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO;
|
|
@ -1,12 +1,17 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.common.core.downstream;
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.core.downstream.router.IotDeviceServiceInvokeVertxHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDeviceServiceInvokeVertxHandler;
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.http.HttpServer;
|
||||
import io.vertx.ext.web.Router;
|
||||
import io.vertx.ext.web.handler.BodyHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* IoT 设备下行服务端,接收来自 server 服务器的请求,转发给 device 设备
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
public class IotDeviceDownstreamServer {
|
||||
|
||||
|
@ -25,6 +30,9 @@ public class IotDeviceDownstreamServer {
|
|||
this.server = vertx.createHttpServer().requestHandler(router);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 HTTP 服务器
|
||||
*/
|
||||
public void start() {
|
||||
log.info("[start][开始启动]");
|
||||
server.listen(0) // 通过 0 自动选择端口
|
||||
|
@ -34,6 +42,9 @@ public class IotDeviceDownstreamServer {
|
|||
log.info("[start][启动完成,端口({})]", this.server.actualPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止所有
|
||||
*/
|
||||
public void stop() {
|
||||
log.info("[stop][开始关闭]");
|
||||
try {
|
|
@ -1,6 +1,6 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.common.core.downstream.router;
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.core.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import lombok.RequiredArgsConstructor;
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.common.core.upstream;
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.upstream;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
|
|
@ -1 +1 @@
|
|||
cn.iocoder.yudao.module.iot.plugin.common.config.YudaoDeviceDataApiAutoConfiguration
|
||||
cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonAutoConfiguration
|
|
@ -1,5 +1,5 @@
|
|||
plugin.id=yudao-module-iot-plugin-http
|
||||
plugin.class=cn.iocoder.yudao.module.iot.plugin.http.config.HttpVertxPlugin
|
||||
plugin.class=cn.iocoder.yudao.module.iot.plugin.http.config.IotHttpVertxPlugin
|
||||
plugin.version=1.0.0
|
||||
plugin.provider=yudao
|
||||
plugin.dependencies=
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<properties>
|
||||
<!-- 插件相关 -->
|
||||
<plugin.id>${project.artifactId}</plugin.id>
|
||||
<plugin.class>cn.iocoder.yudao.module.iot.plugin.http.config.HttpVertxPlugin</plugin.class>
|
||||
<plugin.class>cn.iocoder.yudao.module.iot.plugin.http.config.IotHttpVertxPlugin</plugin.class>
|
||||
<plugin.version>${project.version}</plugin.version>
|
||||
<plugin.provider>yudao</plugin.provider>
|
||||
<plugin.description>${project.artifactId}-${project.version}</plugin.description>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.plugin.http.config.VertxService;
|
||||
import cn.iocoder.yudao.module.iot.plugin.http.upstream.IotDeviceUpstreamServer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
|
@ -21,8 +21,8 @@ public class HttpPluginSpringbootApplication {
|
|||
|
||||
// 手动获取 VertxService 并启动
|
||||
// TODO @haohao:可以放在 bean 的 init 里么?回复:会和插件模式冲突 @芋艿,测试下
|
||||
VertxService vertxService = context.getBean(VertxService.class);
|
||||
vertxService.startServer();
|
||||
IotDeviceUpstreamServer vertxService = context.getBean(IotDeviceUpstreamServer.class);
|
||||
vertxService.start();
|
||||
|
||||
log.info("[HttpPluginSpringbootApplication] 独立模式启动完成");
|
||||
}
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http.config;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
|
||||
import cn.iocoder.yudao.module.iot.plugin.http.framework.upstream.HttpVertxHandler;
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.ext.web.Router;
|
||||
import io.vertx.ext.web.handler.BodyHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 插件与独立运行都可复用的配置类
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class HttpVertxPluginConfiguration {
|
||||
|
||||
// TODO @haohao:这个要不要搞个配置类,更容易维护;
|
||||
/**
|
||||
* 可在 application.yml 中配置,默认端口 8092
|
||||
*/
|
||||
@Value("${plugin.http.server.port:8092}")
|
||||
private Integer port;
|
||||
|
||||
/**
|
||||
* 创建 Vert.x 实例
|
||||
*/
|
||||
@Bean
|
||||
public Vertx vertx() {
|
||||
return Vertx.vertx();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建路由
|
||||
*
|
||||
* @param vertx Vertx 实例
|
||||
* @param httpVertxHandler HttpVertxHandler 实例
|
||||
* @return Router 实例
|
||||
*/
|
||||
@Bean
|
||||
public Router router(Vertx vertx, HttpVertxHandler httpVertxHandler) {
|
||||
Router router = Router.router(vertx);
|
||||
|
||||
// 处理 Body
|
||||
router.route().handler(BodyHandler.create());
|
||||
|
||||
// 设置路由
|
||||
// TODO @haohao:这个后续,我们是多个 Handler ,还是一个哈?
|
||||
router.post("/sys/:productKey/:deviceName/thing/event/property/post")
|
||||
.handler(httpVertxHandler);
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 HttpVertxHandler 实例
|
||||
*
|
||||
* @param deviceDataApi DeviceDataApi 实例
|
||||
* @return HttpVertxHandler 实例
|
||||
*/
|
||||
@Bean
|
||||
public HttpVertxHandler httpVertxHandler(IotDeviceUpstreamApi deviceDataApi) {
|
||||
return new HttpVertxHandler(deviceDataApi);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义一个 VertxService 来管理服务器启动逻辑
|
||||
* 无论是独立运行还是插件方式,都可以共用此类
|
||||
*
|
||||
* @param vertx Vertx 实例
|
||||
* @param router Router 实例
|
||||
* @return VertxService 实例
|
||||
*/
|
||||
@Bean
|
||||
public VertxService vertxService(Vertx vertx, Router router) {
|
||||
return new VertxService(port, vertx, router);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.plugin.http.config;
|
|||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
|
||||
import cn.iocoder.yudao.module.iot.plugin.http.upstream.IotDeviceUpstreamServer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.pf4j.spring.SpringPlugin;
|
||||
|
@ -14,9 +15,9 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
|||
* 负责插件的启动和停止,与 Vert.x 的生命周期管理
|
||||
*/
|
||||
@Slf4j
|
||||
public class HttpVertxPlugin extends SpringPlugin {
|
||||
public class IotHttpVertxPlugin extends SpringPlugin {
|
||||
|
||||
public HttpVertxPlugin(PluginWrapper wrapper) {
|
||||
public IotHttpVertxPlugin(PluginWrapper wrapper) {
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
|
@ -29,8 +30,8 @@ public class HttpVertxPlugin extends SpringPlugin {
|
|||
Assert.notNull(pluginContext, "pluginContext 不能为空");
|
||||
|
||||
// 2. 启动 Vert.x
|
||||
VertxService vertxService = pluginContext.getBean(VertxService.class);
|
||||
vertxService.startServer();
|
||||
IotDeviceUpstreamServer vertxService = pluginContext.getBean(IotDeviceUpstreamServer.class);
|
||||
vertxService.start();
|
||||
|
||||
log.info("[HttpVertxPlugin][HttpVertxPlugin 插件启动成功...]");
|
||||
} catch (Exception e) {
|
||||
|
@ -45,7 +46,7 @@ public class HttpVertxPlugin extends SpringPlugin {
|
|||
// 停止服务器
|
||||
ApplicationContext pluginContext = getApplicationContext();
|
||||
if (pluginContext != null) {
|
||||
VertxService vertxService = pluginContext.getBean(VertxService.class);
|
||||
IotDeviceUpstreamServer vertxService = pluginContext.getBean(IotDeviceUpstreamServer.class);
|
||||
vertxService.stopServer();
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http.config;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
|
||||
import cn.iocoder.yudao.module.iot.plugin.http.upstream.IotDeviceUpstreamServer;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 插件与独立运行都可复用的配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class IotPluginHttpAutoConfiguration {
|
||||
|
||||
// TODO @haohao:这个要不要搞个配置类,更容易维护;
|
||||
/**
|
||||
* 可在 application.yml 中配置,默认端口 8092
|
||||
*/
|
||||
@Value("${plugin.http.server.port:8092}")
|
||||
private Integer port;
|
||||
|
||||
@Bean
|
||||
public IotDeviceUpstreamServer vertxService(IotDeviceUpstreamApi deviceUpstreamApi) {
|
||||
return new IotDeviceUpstreamServer(port, deviceUpstreamApi);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http.config;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.ext.web.Router;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 封装 Vert.x HTTP 服务的启动/关闭逻辑
|
||||
*/
|
||||
@Slf4j
|
||||
public class VertxService {
|
||||
|
||||
private final Integer port;
|
||||
private final Vertx vertx;
|
||||
private final Router router;
|
||||
|
||||
public VertxService(Integer port, Vertx vertx, Router router) {
|
||||
this.port = port;
|
||||
this.vertx = vertx;
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 HTTP 服务器
|
||||
*/
|
||||
public void startServer() {
|
||||
vertx.createHttpServer()
|
||||
.requestHandler(router)
|
||||
.listen(port, http -> {
|
||||
if (http.succeeded()) {
|
||||
log.info("[VertxService] HTTP 服务器启动成功, 端口: {}", port);
|
||||
} else {
|
||||
log.error("[VertxService] HTTP 服务器启动失败", http.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭 HTTP 服务器
|
||||
*/
|
||||
public void stopServer() {
|
||||
if (vertx != null) {
|
||||
vertx.close(ar -> {
|
||||
if (ar.succeeded()) {
|
||||
log.info("[VertxService] Vert.x 关闭成功");
|
||||
} else {
|
||||
log.error("[VertxService] Vert.x 关闭失败", ar.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http.framework.downstream;
|
||||
package cn.iocoder.yudao.module.iot.plugin.http.downstream;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertySetReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.core.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component // TODO @芋艿:后续统一处理
|
|
@ -1 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http.framework;
|
|
@ -0,0 +1,78 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http.upstream;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
|
||||
import cn.iocoder.yudao.module.iot.plugin.http.upstream.router.IotDevicePropertyReportVertxHandler;
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.http.HttpServer;
|
||||
import io.vertx.ext.web.Router;
|
||||
import io.vertx.ext.web.handler.BodyHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* IoT 设备下行服务端,接收来自 device 设备的请求,转发给 server 服务器
|
||||
*
|
||||
* 协议:HTTP
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@Slf4j
|
||||
public class IotDeviceUpstreamServer {
|
||||
|
||||
private final Vertx vertx;
|
||||
private final HttpServer server;
|
||||
private final Integer port;
|
||||
|
||||
public IotDeviceUpstreamServer(Integer port,
|
||||
IotDeviceUpstreamApi deviceUpstreamApi) {
|
||||
this.port = port;
|
||||
// 创建 Vertx 实例
|
||||
this.vertx = Vertx.vertx();
|
||||
// 创建 Router 实例
|
||||
Router router = Router.router(vertx);
|
||||
router.route().handler(BodyHandler.create()); // 处理 Body
|
||||
router.post(IotDevicePropertyReportVertxHandler.PATH)
|
||||
.handler(new IotDevicePropertyReportVertxHandler(deviceUpstreamApi)); // 处理设备属性上报
|
||||
// 创建 HttpServer 实例
|
||||
this.server = vertx.createHttpServer().requestHandler(router);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 HTTP 服务器
|
||||
*/
|
||||
public void start() {
|
||||
log.info("[start][开始启动]");
|
||||
server.listen(port)
|
||||
.toCompletionStage()
|
||||
.toCompletableFuture()
|
||||
.join();
|
||||
log.info("[start][启动完成,端口({})]", this.server.actualPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止所有
|
||||
*/
|
||||
public void stopServer() {
|
||||
log.info("[stop][开始关闭]");
|
||||
try {
|
||||
// 关闭 HTTP 服务器
|
||||
if (server != null) {
|
||||
server.close()
|
||||
.toCompletionStage()
|
||||
.toCompletableFuture()
|
||||
.join();
|
||||
}
|
||||
|
||||
// 关闭 Vertx 实例
|
||||
if (vertx != null) {
|
||||
vertx.close()
|
||||
.toCompletionStage()
|
||||
.toCompletableFuture()
|
||||
.join();
|
||||
}
|
||||
log.info("[stop][关闭完成]");
|
||||
} catch (Exception e) {
|
||||
log.error("[stop][关闭异常]", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http.framework.upstream;
|
||||
package cn.iocoder.yudao.module.iot.plugin.http.upstream.router;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
|
@ -16,11 +16,13 @@ import java.time.LocalDateTime;
|
|||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class HttpVertxHandler implements Handler<RoutingContext> {
|
||||
public class IotDevicePropertyReportVertxHandler implements Handler<RoutingContext> {
|
||||
|
||||
public static final String PATH = "/sys/:productKey/:deviceName/thing/event/property/post";
|
||||
|
||||
private final IotDeviceUpstreamApi deviceDataApi;
|
||||
|
||||
public HttpVertxHandler(IotDeviceUpstreamApi deviceDataApi) {
|
||||
public IotDevicePropertyReportVertxHandler(IotDeviceUpstreamApi deviceDataApi) {
|
||||
this.deviceDataApi = deviceDataApi;
|
||||
}
|
||||
|
Loading…
Reference in New Issue