fix: 物联网平台,amqp数据接入并插入TD数据库相关逻辑编码。

This commit is contained in:
tianyongbao
2026-01-10 01:20:51 +08:00
parent 28c33874f0
commit 0167de4156
56 changed files with 4842 additions and 158 deletions

View File

@@ -0,0 +1,108 @@
package com.intc.iot.utils;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
/**
* 阿里云 IoT AMQP 签名工具类
*
* 用于生成 AMQP 服务端订阅所需的认证信息
*
* @author intc
*/
@Slf4j
@UtilityClass
public class AliyunAmqpSignUtil {
/**
* 生成 AMQP 用户名
*
* @param accessKeyId 阿里云 AccessKey ID
* @return AMQP 用户名
*/
public static String generateUsername(String accessKeyId) {
return accessKeyId + "|authMode=aksign|";
}
/**
* 生成 AMQP 密码
* 使用 HMAC-SHA1 算法对消费组 ID 进行签名
*
* @param accessKeySecret 阿里云 AccessKey Secret
* @param consumerGroupId 消费组 ID
* @return AMQP 密码Base64 编码)
*/
public static String generatePassword(String accessKeySecret, String consumerGroupId) {
try {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secretKeySpec = new SecretKeySpec(
accessKeySecret.getBytes(StandardCharsets.UTF_8),
"HmacSHA1"
);
mac.init(secretKeySpec);
byte[] signData = mac.doFinal(consumerGroupId.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(signData);
} catch (Exception e) {
log.error("生成 AMQP 密码失败", e);
throw new RuntimeException("生成 AMQP 密码失败", e);
}
}
/**
* 生成 AMQP 虚拟主机名
* 默认为 AccessKey ID 的前 8 位
*
* @param accessKeyId 阿里云 AccessKey ID
* @return 虚拟主机名
*/
public static String generateVirtualHost(String accessKeyId) {
if (accessKeyId == null || accessKeyId.length() < 8) {
throw new IllegalArgumentException("AccessKey ID 长度不足 8 位");
}
return accessKeyId.substring(0, 8);
}
/**
* 生成 AMQP 接入点地址
*
* @param uid 阿里云账号 UID
* @param regionId 地域 IDcn-shanghai
* @return AMQP 接入点地址
*/
public static String generateHost(String uid, String regionId) {
return String.format("%s.iot-amqp.%s.aliyuncs.com", uid, regionId);
}
/**
* 打印完整的 AMQP 配置信息(用于调试)
*
* @param accessKeyId AccessKey ID
* @param accessKeySecret AccessKey Secret
* @param consumerGroupId 消费组 ID
* @param uid 阿里云账号 UID
* @param regionId 地域 ID
*/
public static void printAmqpConfig(String accessKeyId, String accessKeySecret,
String consumerGroupId, String uid, String regionId) {
String host = generateHost(uid, regionId);
String virtualHost = generateVirtualHost(accessKeyId);
String username = generateUsername(accessKeyId);
String password = generatePassword(accessKeySecret, consumerGroupId);
log.info("========== AMQP 配置信息 ==========");
log.info("host: {}", host);
log.info("port: 5672");
log.info("virtual-host: {}", virtualHost);
log.info("username: {}", username);
log.info("password: {}", password);
log.info("consumer-group-id: {}", consumerGroupId);
log.info("==================================");
}
}

View File

@@ -0,0 +1,150 @@
package com.intc.iot.utils;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
/**
* 阿里云IoT平台MQTT连接签名工具类
*
* @author intc
*/
@Slf4j
public class AliyunIotSignUtil {
/**
* 生成MQTT ClientId
* 格式:{ClientId}|securemode=2,signmethod=hmacsha1,timestamp={timestamp}|
*
* @param clientId 客户端ID可自定义建议使用设备名称
* @return 完整的ClientId
*/
public static String generateClientId(String clientId) {
long timestamp = System.currentTimeMillis();
return String.format("%s|securemode=2,signmethod=hmacsha1,timestamp=%d|", clientId, timestamp);
}
/**
* 生成MQTT Username
* 格式:{DeviceName}&{ProductKey}
*
* @param deviceName 设备名称
* @param productKey 产品Key
* @return Username
*/
public static String generateUsername(String deviceName, String productKey) {
return String.format("%s&%s", deviceName, productKey);
}
/**
* 生成MQTT Password使用HMAC-SHA1签名
* 签名内容clientId{ClientId}deviceName{DeviceName}productKey{ProductKey}timestamp{timestamp}
*
* @param clientId 客户端ID
* @param deviceName 设备名称
* @param productKey 产品Key
* @param deviceSecret 设备密钥
* @return Password
*/
public static String generatePassword(String clientId, String deviceName, String productKey, String deviceSecret) {
try {
long timestamp = System.currentTimeMillis();
// 构造签名内容
String content = String.format("clientId%sdeviceName%sproductKey%stimestamp%d",
clientId, deviceName, productKey, timestamp);
log.debug("签名内容: {}", content);
// 使用HMAC-SHA1算法签名
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secretKeySpec = new SecretKeySpec(deviceSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA1");
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(content.getBytes(StandardCharsets.UTF_8));
// 转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString().toUpperCase();
} catch (Exception e) {
log.error("生成MQTT密码失败", e);
throw new RuntimeException("生成MQTT密码失败", e);
}
}
/**
* 生成阿里云IoT平台MQTT Broker地址
* 格式:{ProductKey}.iot-as-mqtt.{RegionId}.aliyuncs.com:1883
* SSL格式ssl://{ProductKey}.iot-as-mqtt.{RegionId}.aliyuncs.com:8883
*
* @param productKey 产品Key
* @param regionId 地域IDcn-shanghai
* @param useSsl 是否使用SSL
* @return Broker地址
*/
public static String generateBrokerUrl(String productKey, String regionId, boolean useSsl) {
String protocol = useSsl ? "ssl://" : "tcp://";
int port = useSsl ? 8883 : 1883;
return String.format("%s%s.iot-as-mqtt.%s.aliyuncs.com:%d", protocol, productKey, regionId, port);
}
/**
* 生成设备属性上报Topic
* 格式:/sys/{ProductKey}/{DeviceName}/thing/event/property/post
*
* @param productKey 产品Key
* @param deviceName 设备名称
* @return Topic
*/
public static String generatePropertyTopic(String productKey, String deviceName) {
return String.format("/sys/%s/%s/thing/event/property/post", productKey, deviceName);
}
/**
* 生成所有设备属性上报Topic使用通配符
* 格式:/sys/{ProductKey}/+/thing/event/property/post
*
* @param productKey 产品Key
* @return Topic
*/
public static String generateAllDevicesPropertyTopic(String productKey) {
return String.format("/sys/%s/+/thing/event/property/post", productKey);
}
/**
* 生成设备事件上报Topic
* 格式:/sys/{ProductKey}/{DeviceName}/thing/event/{EventIdentifier}/post
*
* @param productKey 产品Key
* @param deviceName 设备名称
* @param eventIdentifier 事件标识符(使用+通配符可订阅所有事件)
* @return Topic
*/
public static String generateEventTopic(String productKey, String deviceName, String eventIdentifier) {
return String.format("/sys/%s/%s/thing/event/%s/post", productKey, deviceName, eventIdentifier);
}
/**
* 生成设备服务调用Topic
* 格式:/sys/{ProductKey}/{DeviceName}/thing/service/{ServiceIdentifier}
*
* @param productKey 产品Key
* @param deviceName 设备名称
* @param serviceIdentifier 服务标识符
* @return Topic
*/
public static String generateServiceTopic(String productKey, String deviceName, String serviceIdentifier) {
return String.format("/sys/%s/%s/thing/service/%s", productKey, deviceName, serviceIdentifier);
}
}