fix: 物联网平台,amqp数据接入并插入TD数据库相关逻辑编码。
This commit is contained in:
@@ -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 地域 ID(如:cn-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("==================================");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 地域ID(如:cn-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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user