Commit 45b8172a617a15f5a7b34347ed1da208097a2339

Authored by YunaiV
1 parent b4540698

【代码新增】IoT:实现 device 下行属性获取、设置的下行消息

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.http
1 -### 请求 /iot/device/simulation-downstream 接口 => 成功 1 +### 请求 /iot/device/simulation-downstream 接口(服务调用) => 成功
2 POST {{baseUrl}}/iot/device/simulation-downstream 2 POST {{baseUrl}}/iot/device/simulation-downstream
3 Content-Type: application/json 3 Content-Type: application/json
4 tenant-id: {{adminTenentId}} 4 tenant-id: {{adminTenentId}}
@@ -11,4 +11,32 @@ Authorization: Bearer {{token}} @@ -11,4 +11,32 @@ Authorization: Bearer {{token}}
11 "data": { 11 "data": {
12 "xx": "yy" 12 "xx": "yy"
13 } 13 }
  14 +}
  15 +
  16 +### 请求 /iot/device/simulation-downstream 接口(属性设置) => 成功
  17 +POST {{baseUrl}}/iot/device/simulation-downstream
  18 +Content-Type: application/json
  19 +tenant-id: {{adminTenentId}}
  20 +Authorization: Bearer {{token}}
  21 +
  22 +{
  23 + "id": 25,
  24 + "type": "property",
  25 + "identifier": "set",
  26 + "data": {
  27 + "xx": "yy"
  28 + }
  29 +}
  30 +
  31 +### 请求 /iot/device/simulation-downstream 接口(属性获取) => 成功
  32 +POST {{baseUrl}}/iot/device/simulation-downstream
  33 +Content-Type: application/json
  34 +tenant-id: {{adminTenentId}}
  35 +Authorization: Bearer {{token}}
  36 +
  37 +{
  38 + "id": 25,
  39 + "type": "property",
  40 + "identifier": "get",
  41 + "data": ["xx", "yy"]
14 } 42 }
15 \ No newline at end of file 43 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java
@@ -6,6 +6,8 @@ import cn.hutool.core.util.IdUtil; @@ -6,6 +6,8 @@ import cn.hutool.core.util.IdUtil;
6 import cn.iocoder.yudao.framework.common.exception.ServiceException; 6 import cn.iocoder.yudao.framework.common.exception.ServiceException;
7 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 7 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
8 import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceDownstreamAbstractReqDTO; 8 import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceDownstreamAbstractReqDTO;
  9 +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO;
  10 +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertySetReqDTO;
9 import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO; 11 import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO;
10 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceSimulationDownstreamReqVO; 12 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceSimulationDownstreamReqVO;
11 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 13 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
@@ -24,6 +26,7 @@ import org.springframework.validation.annotation.Validated; @@ -24,6 +26,7 @@ import org.springframework.validation.annotation.Validated;
24 import org.springframework.web.client.RestTemplate; 26 import org.springframework.web.client.RestTemplate;
25 27
26 import java.time.LocalDateTime; 28 import java.time.LocalDateTime;
  29 +import java.util.List;
27 import java.util.Map; 30 import java.util.Map;
28 import java.util.Objects; 31 import java.util.Objects;
29 32
@@ -91,11 +94,12 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -91,11 +94,12 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
91 */ 94 */
92 @SuppressWarnings("unchecked") 95 @SuppressWarnings("unchecked")
93 private void invokeDeviceService(IotDeviceSimulationDownstreamReqVO downstreamReqVO, 96 private void invokeDeviceService(IotDeviceSimulationDownstreamReqVO downstreamReqVO,
94 - IotDeviceDO device, IotDeviceDO parentDevice) { 97 + IotDeviceDO device, IotDeviceDO parentDevice) {
95 // 1. 参数校验 98 // 1. 参数校验
96 if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) { 99 if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) {
97 throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型"); 100 throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型");
98 } 101 }
  102 + // TODO @super:【可优化】过滤掉不合法的服务
99 103
100 // 2. 发送请求 104 // 2. 发送请求
101 String url = String.format( "sys/%s/%s/thing/service/%s", 105 String url = String.format( "sys/%s/%s/thing/service/%s",
@@ -125,16 +129,73 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -125,16 +129,73 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
125 * @param device 设备 129 * @param device 设备
126 * @param parentDevice 父设备 130 * @param parentDevice 父设备
127 */ 131 */
  132 + @SuppressWarnings("unchecked")
128 private void setDeviceProperty(IotDeviceSimulationDownstreamReqVO downstreamReqVO, 133 private void setDeviceProperty(IotDeviceSimulationDownstreamReqVO downstreamReqVO,
129 - IotDeviceDO device, IotDeviceDO parentDevice) {  
130 - // TODO 1. 请求 134 + IotDeviceDO device, IotDeviceDO parentDevice) {
  135 + // 1. 参数校验
  136 + if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) {
  137 + throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型");
  138 + }
  139 + // TODO @super:【可优化】过滤掉不合法的属性
  140 +
  141 + // 2. 发送请求
  142 + String url = String.format( "sys/%s/%s/thing/service/property/set",
  143 + getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
  144 + IotDevicePropertySetReqDTO reqDTO = new IotDevicePropertySetReqDTO()
  145 + .setProperties((Map<String, Object>) downstreamReqVO.getData());
  146 + CommonResult<Boolean> result = requestPlugin(url, reqDTO, device);
  147 +
  148 + // 3. 发送设备消息
  149 + IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId())
  150 + .setType(IotDeviceMessageTypeEnum.PROPERTY.getType())
  151 + .setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier())
  152 + .setData(reqDTO.getProperties());
  153 + sendDeviceMessage(message, device, result.getCode());
131 154
132 - // TODO 2. 发送消息 155 + // 4. 如果不成功,抛出异常,提示用户
  156 + if (result.isError()) {
  157 + log.error("[setDeviceProperty][设备({})属性设置失败,请求参数:({}),响应结果:({})]",
  158 + device.getDeviceKey(), reqDTO, result);
  159 + throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg());
  160 + }
133 } 161 }
134 162
  163 + /**
  164 + * 获取设备属性
  165 + *
  166 + * @param downstreamReqVO 下行请求
  167 + * @param device 设备
  168 + * @param parentDevice 父设备
  169 + */
  170 + @SuppressWarnings("unchecked")
135 private void getDeviceProperty(IotDeviceSimulationDownstreamReqVO downstreamReqVO, 171 private void getDeviceProperty(IotDeviceSimulationDownstreamReqVO downstreamReqVO,
136 - IotDeviceDO device, IotDeviceDO parentDevice) {  
137 - // TODO 芋艿:这里需要获取设备属性 172 + IotDeviceDO device, IotDeviceDO parentDevice) {
  173 + // 1. 参数校验
  174 + if (!(downstreamReqVO.getData() instanceof List<?>)) {
  175 + throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 List 类型");
  176 + }
  177 + // TODO @super:【可优化】过滤掉不合法的属性
  178 +
  179 + // 2. 发送请求
  180 + String url = String.format( "sys/%s/%s/thing/service/property/get",
  181 + getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
  182 + IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO()
  183 + .setIdentifiers((List<String>) downstreamReqVO.getData());
  184 + CommonResult<Boolean> result = requestPlugin(url, reqDTO, device);
  185 +
  186 + // 3. 发送设备消息
  187 + IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId())
  188 + .setType(IotDeviceMessageTypeEnum.PROPERTY.getType())
  189 + .setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier())
  190 + .setData(reqDTO.getIdentifiers());
  191 + sendDeviceMessage(message, device, result.getCode());
  192 +
  193 + // 4. 如果不成功,抛出异常,提示用户
  194 + if (result.isError()) {
  195 + log.error("[getDeviceProperty][设备({})属性获取失败,请求参数:({}),响应结果:({})]",
  196 + device.getDeviceKey(), reqDTO, result);
  197 + throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg());
  198 + }
138 } 199 }
139 200
140 /** 201 /**
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/IotDeviceDownstreamServer.java
1 package cn.iocoder.yudao.module.iot.plugin.common.downstream; 1 package cn.iocoder.yudao.module.iot.plugin.common.downstream;
2 2
  3 +import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDevicePropertyGetVertxHandler;
  4 +import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDevicePropertySetVertxHandler;
3 import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDeviceServiceInvokeVertxHandler; 5 import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDeviceServiceInvokeVertxHandler;
4 import io.vertx.core.Vertx; 6 import io.vertx.core.Vertx;
5 import io.vertx.core.http.HttpServer; 7 import io.vertx.core.http.HttpServer;
@@ -24,8 +26,12 @@ public class IotDeviceDownstreamServer { @@ -24,8 +26,12 @@ public class IotDeviceDownstreamServer {
24 // 创建 Router 实例 26 // 创建 Router 实例
25 Router router = Router.router(vertx); 27 Router router = Router.router(vertx);
26 router.route().handler(BodyHandler.create()); // 处理 Body 28 router.route().handler(BodyHandler.create()); // 处理 Body
27 - router.post(IotDeviceServiceInvokeVertxHandler.PATH).handler(  
28 - new IotDeviceServiceInvokeVertxHandler(deviceDownstreamHandler)); // 处理 Service Invoke 29 + router.post(IotDeviceServiceInvokeVertxHandler.PATH)
  30 + .handler(new IotDeviceServiceInvokeVertxHandler(deviceDownstreamHandler));
  31 + router.post(IotDevicePropertySetVertxHandler.PATH)
  32 + .handler(new IotDevicePropertySetVertxHandler(deviceDownstreamHandler));
  33 + router.post(IotDevicePropertyGetVertxHandler.PATH)
  34 + .handler(new IotDevicePropertyGetVertxHandler(deviceDownstreamHandler));
29 // 创建 HttpServer 实例 35 // 创建 HttpServer 实例
30 this.server = vertx.createHttpServer().requestHandler(router); 36 this.server = vertx.createHttpServer().requestHandler(router);
31 } 37 }
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDevicePropertyGetVertxHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO;
  5 +import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
  6 +import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
  7 +import io.vertx.core.Handler;
  8 +import io.vertx.core.json.JsonObject;
  9 +import io.vertx.ext.web.RoutingContext;
  10 +import lombok.RequiredArgsConstructor;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +
  13 +import java.util.List;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
  16 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
  17 +
  18 +/**
  19 + * IOT 设备服务获取 Vertx Handler
  20 + *
  21 + * 芋道源码
  22 + */
  23 +@Slf4j
  24 +@RequiredArgsConstructor
  25 +public class IotDevicePropertyGetVertxHandler implements Handler<RoutingContext> {
  26 +
  27 + public static final String PATH = "/sys/:productKey/:deviceName/thing/service/property/get";
  28 +
  29 + private final IotDeviceDownstreamHandler deviceDownstreamHandler;
  30 +
  31 + @Override
  32 + @SuppressWarnings("unchecked")
  33 + public void handle(RoutingContext routingContext) {
  34 + // 1. 解析参数
  35 + IotDevicePropertyGetReqDTO reqDTO;
  36 + try {
  37 + String productKey = routingContext.pathParam("productKey");
  38 + String deviceName = routingContext.pathParam("deviceName");
  39 + JsonObject body = routingContext.body().asJsonObject();
  40 + String requestId = body.getString("requestId");
  41 + List<String> identifiers = (List<String>) body.getMap().get("identifiers");
  42 + reqDTO = ((IotDevicePropertyGetReqDTO) new IotDevicePropertyGetReqDTO()
  43 + .setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
  44 + .setIdentifiers(identifiers);
  45 + } catch (Exception e) {
  46 + log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
  47 + IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST));
  48 + return;
  49 + }
  50 +
  51 + // 2. 调用处理器
  52 + try {
  53 + CommonResult<Boolean> result = deviceDownstreamHandler.getDeviceProperty(reqDTO);
  54 + IotPluginCommonUtils.writeJson(routingContext, result);
  55 + } catch (Exception e) {
  56 + log.error("[handle][请求参数({}) 属性获取异常]", reqDTO, e);
  57 + IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
  58 + }
  59 + }
  60 +
  61 +}
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDevicePropertySetVertxHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertySetReqDTO;
  5 +import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
  6 +import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
  7 +import io.vertx.core.Handler;
  8 +import io.vertx.core.json.JsonObject;
  9 +import io.vertx.ext.web.RoutingContext;
  10 +import lombok.RequiredArgsConstructor;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +
  13 +import java.util.Map;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
  16 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
  17 +
  18 +/**
  19 + * IOT 设备服务设置 Vertx Handler
  20 + *
  21 + * 芋道源码
  22 + */
  23 +@Slf4j
  24 +@RequiredArgsConstructor
  25 +public class IotDevicePropertySetVertxHandler implements Handler<RoutingContext> {
  26 +
  27 + public static final String PATH = "/sys/:productKey/:deviceName/thing/service/property/set";
  28 +
  29 + private final IotDeviceDownstreamHandler deviceDownstreamHandler;
  30 +
  31 + @Override
  32 + @SuppressWarnings("unchecked")
  33 + public void handle(RoutingContext routingContext) {
  34 + // 1. 解析参数
  35 + IotDevicePropertySetReqDTO reqDTO;
  36 + try {
  37 + String productKey = routingContext.pathParam("productKey");
  38 + String deviceName = routingContext.pathParam("deviceName");
  39 + JsonObject body = routingContext.body().asJsonObject();
  40 + String requestId = body.getString("requestId");
  41 + Map<String, Object> properties = (Map<String, Object>) body.getMap().get("properties");
  42 + reqDTO = ((IotDevicePropertySetReqDTO) new IotDevicePropertySetReqDTO()
  43 + .setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
  44 + .setProperties(properties);
  45 + } catch (Exception e) {
  46 + log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
  47 + IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST));
  48 + return;
  49 + }
  50 +
  51 + // 2. 调用处理器
  52 + try {
  53 + CommonResult<Boolean> result = deviceDownstreamHandler.setDeviceProperty(reqDTO);
  54 + IotPluginCommonUtils.writeJson(routingContext, result);
  55 + } catch (Exception e) {
  56 + log.error("[handle][请求参数({}) 属性设置异常]", reqDTO, e);
  57 + IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
  58 + }
  59 + }
  60 +
  61 +}
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDeviceServiceInvokeVertxHandler.java
@@ -14,6 +14,11 @@ import java.util.Map; @@ -14,6 +14,11 @@ import java.util.Map;
14 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; 14 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
15 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR; 15 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
16 16
  17 +/**
  18 + * IOT 设备服务调用 Vertx Handler
  19 + *
  20 + * 芋道源码
  21 + */
17 @Slf4j 22 @Slf4j
18 @RequiredArgsConstructor 23 @RequiredArgsConstructor
19 public class IotDeviceServiceInvokeVertxHandler implements Handler<RoutingContext> { 24 public class IotDeviceServiceInvokeVertxHandler implements Handler<RoutingContext> {
@@ -26,7 +31,7 @@ public class IotDeviceServiceInvokeVertxHandler implements Handler&lt;RoutingContex @@ -26,7 +31,7 @@ public class IotDeviceServiceInvokeVertxHandler implements Handler&lt;RoutingContex
26 @SuppressWarnings("unchecked") 31 @SuppressWarnings("unchecked")
27 public void handle(RoutingContext routingContext) { 32 public void handle(RoutingContext routingContext) {
28 // 1. 解析参数 33 // 1. 解析参数
29 - IotDeviceServiceInvokeReqDTO invokeReqDTO; 34 + IotDeviceServiceInvokeReqDTO reqDTO;
30 try { 35 try {
31 String productKey = routingContext.pathParam("productKey"); 36 String productKey = routingContext.pathParam("productKey");
32 String deviceName = routingContext.pathParam("deviceName"); 37 String deviceName = routingContext.pathParam("deviceName");
@@ -34,21 +39,21 @@ public class IotDeviceServiceInvokeVertxHandler implements Handler&lt;RoutingContex @@ -34,21 +39,21 @@ public class IotDeviceServiceInvokeVertxHandler implements Handler&lt;RoutingContex
34 JsonObject body = routingContext.body().asJsonObject(); 39 JsonObject body = routingContext.body().asJsonObject();
35 String requestId = body.getString("requestId"); 40 String requestId = body.getString("requestId");
36 Map<String, Object> params = (Map<String, Object>) body.getMap().get("params"); 41 Map<String, Object> params = (Map<String, Object>) body.getMap().get("params");
37 - invokeReqDTO = ((IotDeviceServiceInvokeReqDTO) new IotDeviceServiceInvokeReqDTO() 42 + reqDTO = ((IotDeviceServiceInvokeReqDTO) new IotDeviceServiceInvokeReqDTO()
38 .setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName)) 43 .setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
39 .setIdentifier(identifier).setParams(params); 44 .setIdentifier(identifier).setParams(params);
40 } catch (Exception e) { 45 } catch (Exception e) {
41 - log.error("[handle][解析参数失败]", e); 46 + log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
42 IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST)); 47 IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST));
43 return; 48 return;
44 } 49 }
45 50
46 - // 2. 调用下游处理器 51 + // 2. 调用处理器
47 try { 52 try {
48 - CommonResult<Boolean> result = deviceDownstreamHandler.invokeDeviceService(invokeReqDTO); 53 + CommonResult<Boolean> result = deviceDownstreamHandler.invokeDeviceService(reqDTO);
49 IotPluginCommonUtils.writeJson(routingContext, result); 54 IotPluginCommonUtils.writeJson(routingContext, result);
50 } catch (Exception e) { 55 } catch (Exception e) {
51 - log.error("[handle][请求参数({}) 服务调用异常]", invokeReqDTO, e); 56 + log.error("[handle][请求参数({}) 服务调用异常]", reqDTO, e);
52 IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR)); 57 IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
53 } 58 }
54 } 59 }