【代码优化】IoT:优化 http 插件 IotDevicePropertyReportVertxHandler 的代码
This commit is contained in:
parent
7f0de1e34e
commit
2512f2dde8
|
@ -5,6 +5,7 @@ import lombok.Data;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
// TODO @芋艿:从 server => plugin => device 是否有必要?从阿里云 iot 来看,没有这个功能?!
|
||||
/**
|
||||
* IoT 设备【属性】获取 Request DTO
|
||||
*
|
||||
|
|
|
@ -6,10 +6,11 @@ import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEven
|
|||
import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDevicePropertyReportReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
|
||||
|
||||
/**
|
||||
* 设备数据 Upstream 上行客户端
|
||||
|
@ -18,60 +19,51 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class IotDeviceUpstreamClient implements IotDeviceUpstreamApi {
|
||||
|
||||
public static final String URL_PREFIX = "/rpc-api/iot/device/upstream";
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
// TODO @芋艿:改个名字
|
||||
private final String deviceDataUrl;
|
||||
|
||||
// 可以通过构造器把 RestTemplate 和 baseUrl 注入进来
|
||||
// TODO @haohao:可以用 lombok 简化
|
||||
public IotDeviceUpstreamClient(RestTemplate restTemplate, String deviceDataUrl) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.deviceDataUrl = deviceDataUrl;
|
||||
}
|
||||
|
||||
// TODO @haohao:返回结果,不用 CommonResult 哈。
|
||||
@Override
|
||||
public CommonResult<Boolean> updateDeviceState(IotDeviceStateUpdateReqDTO updateReqDTO) {
|
||||
String url = deviceDataUrl + URL_PREFIX + "/update-state";
|
||||
return doPost(url, updateReqDTO, "updateDeviceState");
|
||||
return doPost(url, updateReqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) {
|
||||
String url = deviceDataUrl + URL_PREFIX + "/report-event";
|
||||
return doPost(url, reportReqDTO, "reportDeviceEventData");
|
||||
return doPost(url, reportReqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) {
|
||||
String url = deviceDataUrl + URL_PREFIX + "/report-property";
|
||||
return doPost(url, reportReqDTO, "reportDevicePropertyData");
|
||||
return doPost(url, reportReqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> heartbeatPluginInstance(IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO) {
|
||||
String url = deviceDataUrl + URL_PREFIX + "/heartbeat-plugin-instance";
|
||||
return doPost(url, heartbeatReqDTO, "heartbeatPluginInstance");
|
||||
return doPost(url, heartbeatReqDTO);
|
||||
}
|
||||
|
||||
// TODO @haohao:未来可能有 get 类型哈
|
||||
/**
|
||||
* 将与远程服务交互的通用逻辑抽取成一个私有方法
|
||||
*/
|
||||
private <T> CommonResult<Boolean> doPost(String url, T requestBody, String actionName) {
|
||||
log.info("[{}] Sending request to URL: {}", actionName, url);
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> CommonResult<Boolean> doPost(String url, T requestBody) {
|
||||
try {
|
||||
// 这里指定返回类型为 CommonResult<?>,根据后台服务返回的实际结构做调整
|
||||
restTemplate.postForObject(url, requestBody, CommonResult.class);
|
||||
// TODO @haohao:check 结果,是否成功
|
||||
return success(true);
|
||||
CommonResult<Boolean> result = restTemplate.postForObject(url, requestBody,
|
||||
(Class<CommonResult<Boolean>>) (Class<?>) CommonResult.class);
|
||||
log.info("[doPost][url({}) requestBody({}) result({})]", url, requestBody, result);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error("[{}] Error sending request to URL: {}", actionName, url, e);
|
||||
return CommonResult.error(400, "Request error: " + e.getMessage());
|
||||
log.error("[doPost][url({}) requestBody({}) 发生异常]", url, requestBody, e);
|
||||
return CommonResult.error(INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ public class IotDeviceUpstreamServer {
|
|||
Router router = Router.router(vertx);
|
||||
router.route().handler(BodyHandler.create()); // 处理 Body
|
||||
router.post(IotDevicePropertyReportVertxHandler.PATH)
|
||||
.handler(new IotDevicePropertyReportVertxHandler(deviceUpstreamApi)); // 处理设备属性上报
|
||||
.handler(new IotDevicePropertyReportVertxHandler(deviceUpstreamApi));
|
||||
// 创建 HttpServer 实例
|
||||
this.server = vertx.createHttpServer().requestHandler(router);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package cn.iocoder.yudao.module.iot.plugin.http.upstream.router;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDevicePropertyReportReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
|
||||
import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RequestBody;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -17,8 +17,13 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import java.time.LocalDateTime;
|
||||
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 设备属性上报的 Vert.x Handler
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
|
@ -29,69 +34,43 @@ public class IotDevicePropertyReportVertxHandler implements Handler<RoutingConte
|
|||
private final IotDeviceUpstreamApi deviceUpstreamApi;
|
||||
|
||||
@Override
|
||||
public void handle(RoutingContext ctx) {
|
||||
String productKey = ctx.pathParam("productKey");
|
||||
String deviceName = ctx.pathParam("deviceName");
|
||||
|
||||
// TODO @haohao:requestBody.asJsonObject() 貌似天然就是 json 对象哈?
|
||||
RequestBody requestBody = ctx.body();
|
||||
JSONObject jsonData;
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handle(RoutingContext routingContext) {
|
||||
// 1. 解析参数
|
||||
IotDevicePropertyReportReqDTO reportReqDTO;
|
||||
try {
|
||||
jsonData = JSONUtil.parseObj(requestBody.asJsonObject());
|
||||
String productKey = routingContext.pathParam("productKey");
|
||||
String deviceName = routingContext.pathParam("deviceName");
|
||||
JsonObject body = routingContext.body().asJsonObject();
|
||||
String id = ObjUtil.defaultIfBlank(body.getString("id"), IdUtil.fastSimpleUUID());
|
||||
Map<String, Object> properties = (Map<String, Object>) body.getMap().get("properties");
|
||||
reportReqDTO = ((IotDevicePropertyReportReqDTO)
|
||||
new IotDevicePropertyReportReqDTO().setRequestId(id)
|
||||
.setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
|
||||
.setProductKey(productKey).setDeviceName(deviceName))
|
||||
.setProperties(properties);
|
||||
} catch (Exception e) {
|
||||
log.error("[HttpVertxHandler] 请求数据解析失败", e);
|
||||
ctx.response().setStatusCode(400)
|
||||
.putHeader("Content-Type", "application/json; charset=UTF-8")
|
||||
.end(createResponseJson(400, null, null,
|
||||
"请求数据不是合法的 JSON 格式: " + e.getMessage(),
|
||||
"thing.event.property.post", "1.0").toString());
|
||||
log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
|
||||
IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST));
|
||||
return;
|
||||
}
|
||||
|
||||
String id = jsonData.getStr("id");
|
||||
|
||||
try {
|
||||
// 设备上线
|
||||
// 2. 设备上线
|
||||
deviceUpstreamApi.updateDeviceState(((IotDeviceStateUpdateReqDTO)
|
||||
new IotDeviceStateUpdateReqDTO().setRequestId(IdUtil.fastSimpleUUID())
|
||||
.setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
|
||||
.setProductKey(productKey).setDeviceName(deviceName))
|
||||
.setProductKey(reportReqDTO.getProductKey()).setDeviceName(reportReqDTO.getDeviceName()))
|
||||
.setState(IotDeviceStateEnum.ONLINE.getState()));
|
||||
|
||||
// 属性上报
|
||||
deviceUpstreamApi.reportDeviceProperty(((IotDevicePropertyReportReqDTO)
|
||||
new IotDevicePropertyReportReqDTO().setRequestId(IdUtil.fastSimpleUUID())
|
||||
.setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
|
||||
.setProductKey(productKey).setDeviceName(deviceName))
|
||||
.setProperties((Map<String, Object>) requestBody.asJsonObject().getMap().get("properties")));
|
||||
|
||||
ctx.response()
|
||||
.setStatusCode(200)
|
||||
.putHeader("Content-Type", "application/json; charset=UTF-8")
|
||||
.end(createResponseJson(200, new JSONObject(), id, "success",
|
||||
"thing.event.property.post", "1.0").toString());
|
||||
// 3.1 属性上报
|
||||
CommonResult<Boolean> result = deviceUpstreamApi.reportDeviceProperty(reportReqDTO);
|
||||
// 3.2 返回结果
|
||||
IotPluginCommonUtils.writeJson(routingContext, result);
|
||||
} catch (Exception e) {
|
||||
log.error("[HttpVertxHandler] 上报属性数据失败", e);
|
||||
ctx.response()
|
||||
.setStatusCode(500)
|
||||
.putHeader("Content-Type", "application/json; charset=UTF-8")
|
||||
.end(createResponseJson(500, new JSONObject(), id,
|
||||
"The format of result is error!",
|
||||
"thing.event.property.post", "1.0").toString());
|
||||
log.error("[handle][请求参数({}) 属性获取异常]", reportReqDTO, e);
|
||||
IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @芋艿:抽一个 IotPluginCommonResult 出来?等 mqtt、websocket 出来后,再考虑优化!
|
||||
private JSONObject createResponseJson(int code, JSONObject data, String id,
|
||||
String message, String method, String version) {
|
||||
JSONObject res = new JSONObject();
|
||||
res.set("code", code);
|
||||
res.set("data", data != null ? data : new JSONObject());
|
||||
res.set("id", id);
|
||||
res.set("message", message);
|
||||
res.set("method", method);
|
||||
res.set("version", version);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue