补全后端基础相关模块
This commit is contained in:
27
yudao-module-iot/yudao-module-iot-plugins/pom.xml
Normal file
27
yudao-module-iot/yudao-module-iot-plugins/pom.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yudao-module-iot</artifactId>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modules>
|
||||
<module>yudao-module-iot-plugin-common</module>
|
||||
<module>yudao-module-iot-plugin-http</module>
|
||||
<module>yudao-module-iot-plugin-mqtt</module>
|
||||
<module>yudao-module-iot-plugin-emqx</module>
|
||||
</modules>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yudao-module-iot-plugins</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
物联网 插件 模块
|
||||
</description>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yudao-module-iot-plugins</artifactId>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yudao-module-iot-plugin-common</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
<!-- TODO @芋艿:注释 -->
|
||||
物联网 插件 模块 - 通用功能
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-iot-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 参数校验 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,52 @@
|
||||
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.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamServer;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.heartbeat.IotPluginInstanceHeartbeatJob;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.upstream.IotDeviceUpstreamClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* IoT 插件的通用自动配置类
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(IotPluginCommonProperties.class)
|
||||
@EnableScheduling // 开启定时任务,因为 IotPluginInstanceHeartbeatJob 是一个定时任务
|
||||
public class IotPluginCommonAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate(IotPluginCommonProperties properties) {
|
||||
return new RestTemplateBuilder()
|
||||
.setConnectTimeout(properties.getUpstreamConnectTimeout())
|
||||
.setReadTimeout(properties.getUpstreamReadTimeout())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IotDeviceUpstreamApi deviceUpstreamApi(IotPluginCommonProperties properties,
|
||||
RestTemplate restTemplate) {
|
||||
return new IotDeviceUpstreamClient(properties, restTemplate);
|
||||
}
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
public IotDeviceDownstreamServer deviceDownstreamServer(IotPluginCommonProperties properties,
|
||||
IotDeviceDownstreamHandler deviceDownstreamHandler) {
|
||||
return new IotDeviceDownstreamServer(properties, deviceDownstreamHandler);
|
||||
}
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "stop")
|
||||
public IotPluginInstanceHeartbeatJob pluginInstanceHeartbeatJob(IotDeviceUpstreamApi deviceDataApi,
|
||||
IotDeviceDownstreamServer deviceDownstreamServer,
|
||||
IotPluginCommonProperties commonProperties) {
|
||||
return new IotPluginInstanceHeartbeatJob(deviceDataApi, deviceDownstreamServer, commonProperties);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* IoT 插件的通用配置类
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "yudao.iot.plugin.common")
|
||||
@Validated
|
||||
@Data
|
||||
public class IotPluginCommonProperties {
|
||||
|
||||
/**
|
||||
* 上行连接超时的默认值
|
||||
*/
|
||||
public static final Duration UPSTREAM_CONNECT_TIMEOUT_DEFAULT = Duration.ofSeconds(30);
|
||||
/**
|
||||
* 上行读取超时的默认值
|
||||
*/
|
||||
public static final Duration UPSTREAM_READ_TIMEOUT_DEFAULT = Duration.ofSeconds(30);
|
||||
|
||||
/**
|
||||
* 下行端口 - 随机
|
||||
*/
|
||||
public static final Integer DOWNSTREAM_PORT_RANDOM = 0;
|
||||
|
||||
/**
|
||||
* 上行 URL
|
||||
*/
|
||||
@NotEmpty(message = "上行 URL 不能为空")
|
||||
private String upstreamUrl;
|
||||
/**
|
||||
* 上行连接超时
|
||||
*/
|
||||
private Duration upstreamConnectTimeout = UPSTREAM_CONNECT_TIMEOUT_DEFAULT;
|
||||
/**
|
||||
* 上行读取超时
|
||||
*/
|
||||
private Duration upstreamReadTimeout = UPSTREAM_READ_TIMEOUT_DEFAULT;
|
||||
|
||||
/**
|
||||
* 下行端口
|
||||
*/
|
||||
private Integer downstreamPort = DOWNSTREAM_PORT_RANDOM;
|
||||
|
||||
/**
|
||||
* 插件包标识符
|
||||
*/
|
||||
@NotEmpty(message = "插件包标识符不能为空")
|
||||
private String pluginKey;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
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.*;
|
||||
|
||||
/**
|
||||
* IoT 设备下行处理器
|
||||
*
|
||||
* 目的:每个 plugin 需要实现,用于处理 server 下行的指令(请求),从而实现从 server => plugin => device 的下行流程
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface IotDeviceDownstreamHandler {
|
||||
|
||||
/**
|
||||
* 调用设备服务
|
||||
*
|
||||
* @param invokeReqDTO 调用设备服务的请求
|
||||
* @return 是否成功
|
||||
*/
|
||||
CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO);
|
||||
|
||||
/**
|
||||
* 获取设备属性
|
||||
*
|
||||
* @param getReqDTO 获取设备属性的请求
|
||||
* @return 是否成功
|
||||
*/
|
||||
CommonResult<Boolean> getDeviceProperty(IotDevicePropertyGetReqDTO getReqDTO);
|
||||
|
||||
/**
|
||||
* 设置设备属性
|
||||
*
|
||||
* @param setReqDTO 设置设备属性的请求
|
||||
* @return 是否成功
|
||||
*/
|
||||
CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO);
|
||||
|
||||
/**
|
||||
* 设置设备配置
|
||||
*
|
||||
* @param setReqDTO 设置设备配置的请求
|
||||
* @return 是否成功
|
||||
*/
|
||||
CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO);
|
||||
|
||||
/**
|
||||
* 升级设备 OTA
|
||||
*
|
||||
* @param upgradeReqDTO 升级设备 OTA 的请求
|
||||
* @return 是否成功
|
||||
*/
|
||||
CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.*;
|
||||
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 {
|
||||
|
||||
private final Vertx vertx;
|
||||
private final HttpServer server;
|
||||
private final IotPluginCommonProperties properties;
|
||||
|
||||
public IotDeviceDownstreamServer(IotPluginCommonProperties properties,
|
||||
IotDeviceDownstreamHandler deviceDownstreamHandler) {
|
||||
this.properties = properties;
|
||||
// 创建 Vertx 实例
|
||||
this.vertx = Vertx.vertx();
|
||||
// 创建 Router 实例
|
||||
Router router = Router.router(vertx);
|
||||
router.route().handler(BodyHandler.create()); // 处理 Body
|
||||
router.post(IotDeviceServiceInvokeVertxHandler.PATH)
|
||||
.handler(new IotDeviceServiceInvokeVertxHandler(deviceDownstreamHandler));
|
||||
router.post(IotDevicePropertySetVertxHandler.PATH)
|
||||
.handler(new IotDevicePropertySetVertxHandler(deviceDownstreamHandler));
|
||||
router.post(IotDevicePropertyGetVertxHandler.PATH)
|
||||
.handler(new IotDevicePropertyGetVertxHandler(deviceDownstreamHandler));
|
||||
router.post(IotDeviceConfigSetVertxHandler.PATH)
|
||||
.handler(new IotDeviceConfigSetVertxHandler(deviceDownstreamHandler));
|
||||
router.post(IotDeviceOtaUpgradeVertxHandler.PATH)
|
||||
.handler(new IotDeviceOtaUpgradeVertxHandler(deviceDownstreamHandler));
|
||||
// 创建 HttpServer 实例
|
||||
this.server = vertx.createHttpServer().requestHandler(router);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 HTTP 服务器
|
||||
*/
|
||||
public void start() {
|
||||
log.info("[start][开始启动]");
|
||||
server.listen(properties.getDownstreamPort())
|
||||
.toCompletionStage()
|
||||
.toCompletableFuture()
|
||||
.join();
|
||||
log.info("[start][启动完成,端口({})]", this.server.actualPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止所有
|
||||
*/
|
||||
public void stop() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得端口
|
||||
*
|
||||
* @return 端口
|
||||
*/
|
||||
public int getPort() {
|
||||
return this.server.actualPort();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceConfigSetReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.pojo.IotStandardResponse;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
|
||||
|
||||
/**
|
||||
* IoT 设备配置设置 Vertx Handler
|
||||
*
|
||||
* 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class IotDeviceConfigSetVertxHandler implements Handler<RoutingContext> {
|
||||
|
||||
// TODO @haohao:是不是可以把 PATH、Method 所有的,抽到一个枚举类里?因为 topic、path、method 相当于不同的几个表达?
|
||||
public static final String PATH = "/sys/:productKey/:deviceName/thing/service/config/set";
|
||||
public static final String METHOD = "thing.service.config.set";
|
||||
|
||||
private final IotDeviceDownstreamHandler deviceDownstreamHandler;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handle(RoutingContext routingContext) {
|
||||
// 1. 解析参数
|
||||
IotDeviceConfigSetReqDTO reqDTO;
|
||||
try {
|
||||
String productKey = routingContext.pathParam("productKey");
|
||||
String deviceName = routingContext.pathParam("deviceName");
|
||||
JsonObject body = routingContext.body().asJsonObject();
|
||||
String requestId = body.getString("requestId");
|
||||
Map<String, Object> config = (Map<String, Object>) body.getMap().get("config");
|
||||
reqDTO = ((IotDeviceConfigSetReqDTO) new IotDeviceConfigSetReqDTO()
|
||||
.setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
|
||||
.setConfig(config);
|
||||
} catch (Exception e) {
|
||||
log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
|
||||
IotStandardResponse errorResponse = IotStandardResponse.error(
|
||||
null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 调用处理器
|
||||
try {
|
||||
CommonResult<Boolean> result = deviceDownstreamHandler.setDeviceConfig(reqDTO);
|
||||
|
||||
// 3. 响应结果
|
||||
IotStandardResponse response = result.isSuccess() ?
|
||||
IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData())
|
||||
: IotStandardResponse.error(reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, response);
|
||||
} catch (Exception e) {
|
||||
log.error("[handle][请求参数({}) 配置设置异常]", reqDTO, e);
|
||||
IotStandardResponse errorResponse = IotStandardResponse.error(
|
||||
reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceOtaUpgradeReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.pojo.IotStandardResponse;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
|
||||
|
||||
/**
|
||||
* IoT 设备 OTA 升级 Vertx Handler
|
||||
* <p>
|
||||
* 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class IotDeviceOtaUpgradeVertxHandler implements Handler<RoutingContext> {
|
||||
|
||||
public static final String PATH = "/ota/:productKey/:deviceName/upgrade";
|
||||
public static final String METHOD = "ota.device.upgrade";
|
||||
|
||||
private final IotDeviceDownstreamHandler deviceDownstreamHandler;
|
||||
|
||||
@Override
|
||||
public void handle(RoutingContext routingContext) {
|
||||
// 1. 解析参数
|
||||
IotDeviceOtaUpgradeReqDTO reqDTO;
|
||||
try {
|
||||
String productKey = routingContext.pathParam("productKey");
|
||||
String deviceName = routingContext.pathParam("deviceName");
|
||||
JsonObject body = routingContext.body().asJsonObject();
|
||||
String requestId = body.getString("requestId");
|
||||
Long firmwareId = body.getLong("firmwareId");
|
||||
String version = body.getString("version");
|
||||
String signMethod = body.getString("signMethod");
|
||||
String fileSign = body.getString("fileSign");
|
||||
Long fileSize = body.getLong("fileSize");
|
||||
String fileUrl = body.getString("fileUrl");
|
||||
String information = body.getString("information");
|
||||
reqDTO = ((IotDeviceOtaUpgradeReqDTO) new IotDeviceOtaUpgradeReqDTO()
|
||||
.setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
|
||||
.setFirmwareId(firmwareId).setVersion(version)
|
||||
.setSignMethod(signMethod).setFileSign(fileSign).setFileSize(fileSize).setFileUrl(fileUrl)
|
||||
.setInformation(information);
|
||||
} catch (Exception e) {
|
||||
log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
|
||||
IotStandardResponse errorResponse = IotStandardResponse.error(
|
||||
null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 调用处理器
|
||||
try {
|
||||
CommonResult<Boolean> result = deviceDownstreamHandler.upgradeDeviceOta(reqDTO);
|
||||
|
||||
// 3. 响应结果
|
||||
// TODO @haohao:可以考虑 IotStandardResponse.of(requestId, method, CommonResult)
|
||||
IotStandardResponse response = result.isSuccess() ?
|
||||
IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData())
|
||||
:IotStandardResponse.error(reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, response);
|
||||
} catch (Exception e) {
|
||||
log.error("[handle][请求参数({}) OTA 升级异常]", reqDTO, e);
|
||||
// TODO @haohao:可以考虑 IotStandardResponse.of(requestId, method, ErrorCode)
|
||||
IotStandardResponse errorResponse = IotStandardResponse.error(
|
||||
reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
|
||||
|
||||
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.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.pojo.IotStandardResponse;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
|
||||
|
||||
/**
|
||||
* IoT 设备服务获取 Vertx Handler
|
||||
*
|
||||
* 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class IotDevicePropertyGetVertxHandler implements Handler<RoutingContext> {
|
||||
|
||||
public static final String PATH = "/sys/:productKey/:deviceName/thing/service/property/get";
|
||||
public static final String METHOD = "thing.service.property.get";
|
||||
|
||||
private final IotDeviceDownstreamHandler deviceDownstreamHandler;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handle(RoutingContext routingContext) {
|
||||
// 1. 解析参数
|
||||
IotDevicePropertyGetReqDTO reqDTO;
|
||||
try {
|
||||
String productKey = routingContext.pathParam("productKey");
|
||||
String deviceName = routingContext.pathParam("deviceName");
|
||||
JsonObject body = routingContext.body().asJsonObject();
|
||||
String requestId = body.getString("requestId");
|
||||
List<String> identifiers = (List<String>) body.getMap().get("identifiers");
|
||||
reqDTO = ((IotDevicePropertyGetReqDTO) new IotDevicePropertyGetReqDTO()
|
||||
.setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
|
||||
.setIdentifiers(identifiers);
|
||||
} catch (Exception e) {
|
||||
log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
|
||||
IotStandardResponse errorResponse = IotStandardResponse.error(
|
||||
null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 调用处理器
|
||||
try {
|
||||
CommonResult<Boolean> result = deviceDownstreamHandler.getDeviceProperty(reqDTO);
|
||||
|
||||
// 3. 响应结果
|
||||
IotStandardResponse response;
|
||||
if (result.isSuccess()) {
|
||||
response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData());
|
||||
} else {
|
||||
response = IotStandardResponse.error(reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg());
|
||||
}
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, response);
|
||||
} catch (Exception e) {
|
||||
log.error("[handle][请求参数({}) 属性获取异常]", reqDTO, e);
|
||||
IotStandardResponse errorResponse = IotStandardResponse.error(
|
||||
reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertySetReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.pojo.IotStandardResponse;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
|
||||
|
||||
/**
|
||||
* IoT 设置设备属性 Vertx Handler
|
||||
*
|
||||
* 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class IotDevicePropertySetVertxHandler implements Handler<RoutingContext> {
|
||||
|
||||
public static final String PATH = "/sys/:productKey/:deviceName/thing/service/property/set";
|
||||
public static final String METHOD = "thing.service.property.set";
|
||||
|
||||
private final IotDeviceDownstreamHandler deviceDownstreamHandler;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handle(RoutingContext routingContext) {
|
||||
// 1. 解析参数
|
||||
IotDevicePropertySetReqDTO reqDTO;
|
||||
try {
|
||||
String productKey = routingContext.pathParam("productKey");
|
||||
String deviceName = routingContext.pathParam("deviceName");
|
||||
JsonObject body = routingContext.body().asJsonObject();
|
||||
String requestId = body.getString("requestId");
|
||||
Map<String, Object> properties = (Map<String, Object>) body.getMap().get("properties");
|
||||
reqDTO = ((IotDevicePropertySetReqDTO) new IotDevicePropertySetReqDTO()
|
||||
.setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
|
||||
.setProperties(properties);
|
||||
} catch (Exception e) {
|
||||
log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
|
||||
IotStandardResponse errorResponse = IotStandardResponse.error(
|
||||
null, METHOD, BAD_REQUEST.getCode(), BAD_REQUEST.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 调用处理器
|
||||
try {
|
||||
CommonResult<Boolean> result = deviceDownstreamHandler.setDeviceProperty(reqDTO);
|
||||
|
||||
// 3. 响应结果
|
||||
IotStandardResponse response;
|
||||
if (result.isSuccess()) {
|
||||
response = IotStandardResponse.success(reqDTO.getRequestId(), METHOD, result.getData());
|
||||
} else {
|
||||
response = IotStandardResponse.error(reqDTO.getRequestId(), METHOD, result.getCode(), result.getMsg());
|
||||
}
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, response);
|
||||
} catch (Exception e) {
|
||||
log.error("[handle][请求参数({}) 属性设置异常]", reqDTO, e);
|
||||
IotStandardResponse errorResponse = IotStandardResponse.error(
|
||||
reqDTO.getRequestId(), METHOD, INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
|
||||
IotPluginCommonUtils.writeJsonResponse(routingContext, errorResponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user