测试场景:直连设备(IotProductDeviceTypeEnum 的 DIRECT 类型)通过 UDP 协议直接连接平台 * *
使用步骤: *
注意:UDP 协议是无状态的,每次请求需要在 params 中携带 token(与 HTTP 通过 Header 传递不同)
+ *
* @author 芋道源码
*/
@Slf4j
-public class IotUdpProtocolIntegrationTest {
+public class IotDirectDeviceUdpProtocolIntegrationTest {
private static final String SERVER_HOST = "127.0.0.1";
- private static final int SERVER_PORT = 8092;
+ private static final int SERVER_PORT = 8093;
private static final int TIMEOUT_MS = 5000;
- // 设备信息(根据实际情况修改 PRODUCT_KEY、DEVICE_NAME、PASSWORD)
+ // ===================== 直连设备信息(根据实际情况修改,从 iot_device 表查询子设备) =====================
private static final String PRODUCT_KEY = "4aymZgOTOOCrDKRT";
private static final String DEVICE_NAME = "small";
- private static final String PASSWORD = "509e2b08f7598eb139d276388c600435913ba4c94cd0d50aebc5c0d1855bcb75";
-
- // TODO @芋艿:1、IotDeviceAuthUtils 调整下拼接;2、password 的生成;3、后续给 http 也整个单测;4、后续给 tcp 也整个单测;5、后续给 mqtt 也整个单测;6、后续给 emqp 也整个单测
- private static final String CLIENT_ID = PRODUCT_KEY + "." + DEVICE_NAME;
- private static final String USERNAME = DEVICE_NAME + "&" + PRODUCT_KEY;
+ private static final String DEVICE_SECRET = "0baa4c2ecc104ae1a26b4070c218bdf3";
/**
- * 设备 Token:从 {@link #testAuth()} 方法获取后,粘贴到这里
+ * 直连设备 Token:从 {@link #testAuth()} 方法获取后,粘贴到这里
*/
- private static final String TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9kdWN0S2V5IjoiNGF5bVpnT1RPT0NyREtSVCIsImV4cCI6MTc2OTMxMTY0NiwiZGV2aWNlTmFtZSI6InNtYWxsIn0.re6LCaRfKiE9VQTP3w0Brh2ScVIgrvN3H96z_snndoM";
+ private static final String TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9kdWN0S2V5IjoiNGF5bVpnT1RPT0NyREtSVCIsImV4cCI6MTc2OTk0ODYzOCwiZGV2aWNlTmFtZSI6InNtYWxsIn0.TrOJisXhloZ3quLBOAIyowmpq6Syp9PHiEpfj-nQ9xo";
+
+ // ===================== 认证测试 =====================
/**
* 认证测试:获取设备 Token
*/
@Test
public void testAuth() throws Exception {
+ // 1.1 构建请求
+ IotDeviceAuthReqDTO authInfo = IotDeviceAuthUtils.getAuthInfo(PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET);
+ IotDeviceAuthReqDTO authReqDTO = new IotDeviceAuthReqDTO()
+ .setClientId(authInfo.getClientId())
+ .setUsername(authInfo.getUsername())
+ .setPassword(authInfo.getPassword());
String payload = JsonUtils.toJsonString(MapUtil.builder()
.put("id", IdUtil.fastSimpleUUID())
.put("method", "auth")
- .put("params", MapUtil.builder()
- .put("clientId", CLIENT_ID)
- .put("username", USERNAME)
- .put("password", PASSWORD)
- .build())
+ .put("params", authReqDTO)
.build());
+ // 1.2 输出请求
+ log.info("[testAuth][请求体: {}]", payload);
+ // 2.1 发送请求
try (DatagramSocket socket = new DatagramSocket()) {
socket.setSoTimeout(TIMEOUT_MS);
-
- log.info("[testAuth][请求体: {}]", payload);
-
String response = sendAndReceive(socket, payload);
-
+ // 2.2 输出结果
log.info("[testAuth][响应体: {}]", response);
log.info("[testAuth][请将返回的 token 复制到 TOKEN 常量中]");
}
}
+ // ===================== 直连设备属性上报测试 =====================
+
/**
* 属性上报测试
*/
@Test
public void testPropertyPost() throws Exception {
+ // 1.1 构建请求(UDP 协议:token 放在 params 中)
String payload = JsonUtils.toJsonString(MapUtil.builder()
.put("id", IdUtil.fastSimpleUUID())
.put("method", IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod())
.put("version", "1.0")
- .put("params", MapUtil.builder()
- .put("token", TOKEN)
+ .put("params", withToken(IotDevicePropertyPostReqDTO.of(MapUtil.
+ * 使用产品密钥(productSecret)验证身份,成功后返回设备密钥(deviceSecret)
+ *
+ * 注意:此接口不需要 Token 认证
+ */
+ @Test
+ public void testDeviceRegister() throws Exception {
+ // 1.1 构建请求参数
+ IotDeviceRegisterReqDTO reqDTO = new IotDeviceRegisterReqDTO();
+ reqDTO.setProductKey(PRODUCT_KEY);
+ reqDTO.setDeviceName("test-" + System.currentTimeMillis());
+ reqDTO.setProductSecret("test-product-secret");
+ // 1.2 构建请求
+ String payload = JsonUtils.toJsonString(MapUtil.builder()
+ .put("id", IdUtil.fastSimpleUUID())
+ .put("method", IotDeviceMessageMethodEnum.DEVICE_REGISTER.getMethod())
+ .put("params", reqDTO)
+ .build());
+ // 1.3 输出请求
+ log.info("[testDeviceRegister][请求体: {}]", payload);
+
+ // 2.1 发送请求
+ try (DatagramSocket socket = new DatagramSocket()) {
+ socket.setSoTimeout(TIMEOUT_MS);
String response = sendAndReceive(socket, payload);
+ // 2.2 输出结果
+ log.info("[testDeviceRegister][响应体: {}]", response);
+ log.info("[testDeviceRegister][成功后可使用返回的 deviceSecret 进行一机一密认证]");
+ }
+ }
- log.info("[testEventPost][响应体: {}]", response);
+ // ===================== 辅助方法 =====================
+
+ /**
+ * 将 token 添加到 params 中
+ *
+ * 支持 Map 或普通对象,通过 JSON 转换统一处理
+ *
+ * @param params 原始参数(Map 或对象)
+ * @return 添加了 token 的 Map
+ */
+ @SuppressWarnings("unchecked")
+ private Map