feat(iot):【协议改造】SSL 配置,统一使用 SslConfig 替代,更统一

This commit is contained in:
YunaiV
2026-02-04 18:41:31 +08:00
parent a77e1780cc
commit eb9d27ae9e
13 changed files with 109 additions and 107 deletions

View File

@@ -35,7 +35,7 @@ public class IotGatewayProperties {
/**
* 协议实例列表
*/
private List<ProtocolInstanceProperties> protocols;
private List<ProtocolProperties> protocols;
@Data
public static class RpcProperties {
@@ -78,7 +78,7 @@ public class IotGatewayProperties {
* 协议实例配置
*/
@Data
public static class ProtocolInstanceProperties {
public static class ProtocolProperties {
/**
* 协议实例 ID如 "http-alink"、"tcp-binary"
@@ -117,6 +117,14 @@ public class IotGatewayProperties {
*/
private String serialize;
// ========== SSL 配置 ==========
/**
* SSL 配置(可选,配置文件中不配置则为 null
*/
@Valid
private SslConfig ssl;
// ========== 各协议配置 ==========
/**
@@ -160,4 +168,52 @@ public class IotGatewayProperties {
}
/**
* SSL 配置
*/
@Data
public static class SslConfig {
/**
* 是否启用 SSL
*/
@NotNull(message = "是否启用 SSL 不能为空")
private Boolean ssl = false;
/**
* SSL 证书路径
*/
@NotEmpty(message = "SSL 证书路径不能为空")
private String sslCertPath;
/**
* SSL 私钥路径
*/
@NotEmpty(message = "SSL 私钥路径不能为空")
private String sslKeyPath;
/**
* 密钥库KeyStore路径
* <p>
* 包含客户端自己的证书和私钥,用于向服务端证明身份(双向认证)
*/
private String keyStorePath;
/**
* 密钥库密码
*/
private String keyStorePassword;
/**
* 信任库TrustStore路径
* <p>
* 包含服务端信任的 CA 证书,用于验证服务端的身份
*/
private String trustStorePath;
/**
* 信任库密码
*/
private String trustStorePassword;
}
}

View File

@@ -45,13 +45,13 @@ public class IotProtocolManager implements SmartLifecycle {
if (running) {
return;
}
List<IotGatewayProperties.ProtocolInstanceProperties> protocolConfigs = gatewayProperties.getProtocols();
List<IotGatewayProperties.ProtocolProperties> protocolConfigs = gatewayProperties.getProtocols();
if (CollUtil.isEmpty(protocolConfigs)) {
log.info("[start][没有配置协议实例,跳过启动]");
return;
}
for (IotGatewayProperties.ProtocolInstanceProperties config : protocolConfigs) {
for (IotGatewayProperties.ProtocolProperties config : protocolConfigs) {
if (BooleanUtil.isFalse(config.getEnabled())) {
log.info("[start][协议实例 {} 未启用,跳过]", config.getId());
continue;
@@ -91,7 +91,7 @@ public class IotProtocolManager implements SmartLifecycle {
* @return 协议实例
*/
@SuppressWarnings({"EnhancedSwitchMigration"})
private IotProtocol createProtocol(IotGatewayProperties.ProtocolInstanceProperties config) {
private IotProtocol createProtocol(IotGatewayProperties.ProtocolProperties config) {
IotProtocolTypeEnum protocolType = IotProtocolTypeEnum.of(config.getProtocol());
if (protocolType == null) {
log.error("[createProtocol][协议实例 {} 的协议类型 {} 不存在]", config.getId(), config.getProtocol());
@@ -124,7 +124,7 @@ public class IotProtocolManager implements SmartLifecycle {
* @param config 协议实例配置
* @return HTTP 协议实例
*/
private IotHttpProtocol createHttpProtocol(IotGatewayProperties.ProtocolInstanceProperties config) {
private IotHttpProtocol createHttpProtocol(IotGatewayProperties.ProtocolProperties config) {
return new IotHttpProtocol(config);
}
@@ -134,7 +134,7 @@ public class IotProtocolManager implements SmartLifecycle {
* @param config 协议实例配置
* @return TCP 协议实例
*/
private IotTcpProtocol createTcpProtocol(IotGatewayProperties.ProtocolInstanceProperties config) {
private IotTcpProtocol createTcpProtocol(IotGatewayProperties.ProtocolProperties config) {
return new IotTcpProtocol(config);
}
@@ -144,7 +144,7 @@ public class IotProtocolManager implements SmartLifecycle {
* @param config 协议实例配置
* @return UDP 协议实例
*/
private IotUdpProtocol createUdpProtocol(IotGatewayProperties.ProtocolInstanceProperties config) {
private IotUdpProtocol createUdpProtocol(IotGatewayProperties.ProtocolProperties config) {
return new IotUdpProtocol(config);
}
@@ -154,7 +154,7 @@ public class IotProtocolManager implements SmartLifecycle {
* @param config 协议实例配置
* @return CoAP 协议实例
*/
private IotCoapProtocol createCoapProtocol(IotGatewayProperties.ProtocolInstanceProperties config) {
private IotCoapProtocol createCoapProtocol(IotGatewayProperties.ProtocolProperties config) {
return new IotCoapProtocol(config);
}
@@ -164,7 +164,7 @@ public class IotProtocolManager implements SmartLifecycle {
* @param config 协议实例配置
* @return WebSocket 协议实例
*/
private IotWebSocketProtocol createWebSocketProtocol(IotGatewayProperties.ProtocolInstanceProperties config) {
private IotWebSocketProtocol createWebSocketProtocol(IotGatewayProperties.ProtocolProperties config) {
return new IotWebSocketProtocol(config);
}
@@ -174,7 +174,7 @@ public class IotProtocolManager implements SmartLifecycle {
* @param config 协议实例配置
* @return MQTT 协议实例
*/
private IotMqttProtocol createMqttProtocol(IotGatewayProperties.ProtocolInstanceProperties config) {
private IotMqttProtocol createMqttProtocol(IotGatewayProperties.ProtocolProperties config) {
return new IotMqttProtocol(config);
}
@@ -184,7 +184,7 @@ public class IotProtocolManager implements SmartLifecycle {
* @param config 协议实例配置
* @return EMQX 协议实例
*/
private IotEmqxProtocol createEmqxProtocol(IotGatewayProperties.ProtocolInstanceProperties config) {
private IotEmqxProtocol createEmqxProtocol(IotGatewayProperties.ProtocolProperties config) {
return new IotEmqxProtocol(config);
}

View File

@@ -4,7 +4,7 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolInstanceProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolProperties;
import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol;
import cn.iocoder.yudao.module.iot.gateway.protocol.coap.handler.downstream.IotCoapDownstreamSubscriber;
import cn.iocoder.yudao.module.iot.gateway.protocol.coap.handler.upstream.IotCoapAuthHandler;
@@ -43,7 +43,7 @@ public class IotCoapProtocol implements IotProtocol {
/**
* 协议配置
*/
private final ProtocolInstanceProperties properties;
private final ProtocolProperties properties;
/**
* 服务器 ID用于消息追踪全局唯一
*/
@@ -66,7 +66,7 @@ public class IotCoapProtocol implements IotProtocol {
*/
private final IotCoapDownstreamSubscriber downstreamSubscriber;
public IotCoapProtocol(ProtocolInstanceProperties properties) {
public IotCoapProtocol(ProtocolProperties properties) {
IotCoapConfig coapConfig = properties.getCoap();
Assert.notNull(coapConfig, "CoAP 协议配置coap不能为空");
this.properties = properties;

View File

@@ -7,7 +7,7 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolInstanceProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolProperties;
import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol;
import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.handler.downstream.IotEmqxDownstreamSubscriber;
import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.handler.upstream.IotEmqxAuthEventHandler;
@@ -47,7 +47,7 @@ public class IotEmqxProtocol implements IotProtocol {
/**
* 协议配置
*/
private final ProtocolInstanceProperties properties;
private final ProtocolProperties properties;
/**
* EMQX 配置
*/
@@ -92,7 +92,7 @@ public class IotEmqxProtocol implements IotProtocol {
*/
private final IotEmqxDownstreamSubscriber downstreamSubscriber;
public IotEmqxProtocol(ProtocolInstanceProperties properties) {
public IotEmqxProtocol(ProtocolProperties properties) {
Assert.notNull(properties, "协议实例配置不能为空");
Assert.notNull(properties.getEmqx(), "EMQX 协议配置emqx不能为空");
this.properties = properties;

View File

@@ -10,19 +10,4 @@ import lombok.Data;
@Data
public class IotHttpConfig {
/**
* 是否启用 SSL
*/
private Boolean sslEnabled = false;
/**
* SSL 证书路径
*/
private String sslCertPath;
/**
* SSL 私钥路径
*/
private String sslKeyPath;
}

View File

@@ -4,7 +4,8 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolInstanceProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolProperties;
import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol;
import cn.iocoder.yudao.module.iot.gateway.protocol.http.handler.downstream.IotHttpDownstreamSubscriber;
import cn.iocoder.yudao.module.iot.gateway.protocol.http.handler.upstream.IotHttpAuthHandler;
@@ -33,7 +34,7 @@ public class IotHttpProtocol implements IotProtocol {
/**
* 协议配置
*/
private final ProtocolInstanceProperties properties;
private final ProtocolProperties properties;
/**
* 服务器 ID用于消息追踪全局唯一
*/
@@ -60,7 +61,7 @@ public class IotHttpProtocol implements IotProtocol {
*/
private IotHttpDownstreamSubscriber downstreamSubscriber;
public IotHttpProtocol(ProtocolInstanceProperties properties) {
public IotHttpProtocol(ProtocolProperties properties) {
this.properties = properties;
this.serverId = IotDeviceMessageUtils.generateServerId(properties.getPort());
@@ -104,12 +105,12 @@ public class IotHttpProtocol implements IotProtocol {
router.post(IotHttpUpstreamHandler.PATH).handler(upstreamHandler);
// 1.4 启动 HTTP 服务器
IotHttpConfig httpConfig = properties.getHttp();
HttpServerOptions options = new HttpServerOptions().setPort(properties.getPort());
if (httpConfig != null && Boolean.TRUE.equals(httpConfig.getSslEnabled())) {
IotGatewayProperties.SslConfig sslConfig = properties.getSsl();
if (sslConfig != null && Boolean.TRUE.equals(sslConfig.getSsl())) {
PemKeyCertOptions pemKeyCertOptions = new PemKeyCertOptions()
.setKeyPath(httpConfig.getSslKeyPath())
.setCertPath(httpConfig.getSslCertPath());
.setKeyPath(sslConfig.getSslKeyPath())
.setCertPath(sslConfig.getSslCertPath());
options = options.setSsl(true).setKeyCertOptions(pemKeyCertOptions);
}
try {

View File

@@ -26,20 +26,4 @@ public class IotMqttConfig {
@Min(value = 1, message = "连接超时时间不能小于 1 秒")
private Integer connectTimeoutSeconds = 60;
/**
* 是否启用 SSL
*/
@NotNull(message = "是否启用 SSL 不能为空")
private Boolean sslEnabled = false;
/**
* SSL 证书路径
*/
private String sslCertPath;
/**
* SSL 私钥路径
*/
private String sslKeyPath;
}

View File

@@ -8,7 +8,8 @@ import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolInstanceProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolProperties;
import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol;
import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.handler.downstream.IotMqttDownstreamHandler;
import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.handler.downstream.IotMqttDownstreamSubscriber;
@@ -51,7 +52,7 @@ public class IotMqttProtocol implements IotProtocol {
/**
* 协议配置
*/
private final ProtocolInstanceProperties properties;
private final ProtocolProperties properties;
/**
* 服务器 ID用于消息追踪全局唯一
*/
@@ -88,7 +89,7 @@ public class IotMqttProtocol implements IotProtocol {
private final IotMqttRegisterHandler registerHandler;
private final IotMqttUpstreamHandler upstreamHandler;
public IotMqttProtocol(ProtocolInstanceProperties properties) {
public IotMqttProtocol(ProtocolProperties properties) {
IotMqttConfig mqttConfig = properties.getMqtt();
Assert.notNull(mqttConfig, "MQTT 协议配置mqtt不能为空");
this.properties = properties;
@@ -136,10 +137,11 @@ public class IotMqttProtocol implements IotProtocol {
.setPort(properties.getPort())
.setMaxMessageSize(mqttConfig.getMaxMessageSize())
.setTimeoutOnConnect(mqttConfig.getConnectTimeoutSeconds());
if (Boolean.TRUE.equals(mqttConfig.getSslEnabled())) {
IotGatewayProperties.SslConfig sslConfig = properties.getSsl();
if (sslConfig != null && Boolean.TRUE.equals(sslConfig.getSsl())) {
PemKeyCertOptions pemKeyCertOptions = new PemKeyCertOptions()
.setKeyPath(mqttConfig.getSslKeyPath())
.setCertPath(mqttConfig.getSslCertPath());
.setKeyPath(sslConfig.getSslKeyPath())
.setCertPath(sslConfig.getSslCertPath());
options.setSsl(true).setKeyCertOptions(pemKeyCertOptions);
}

View File

@@ -27,20 +27,6 @@ public class IotTcpConfig {
@Min(value = 1000, message = "心跳超时时间必须大于 1000 毫秒")
private Long keepAliveTimeoutMs = 30000L;
/**
* 是否启用 SSL
*/
@NotNull(message = "是否启用 SSL 不能为空")
private Boolean sslEnabled = false;
/**
* SSL 证书路径
*/
private String sslCertPath;
/**
* SSL 私钥路径
*/
private String sslKeyPath;
/**
* 拆包配置
*/

View File

@@ -5,7 +5,8 @@ import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
import cn.iocoder.yudao.module.iot.core.enums.IotSerializeTypeEnum;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolInstanceProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolProperties;
import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol;
import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.codec.IotTcpFrameCodec;
import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.codec.IotTcpFrameCodecFactory;
@@ -36,7 +37,7 @@ public class IotTcpProtocol implements IotProtocol {
/**
* 协议配置
*/
private final ProtocolInstanceProperties properties;
private final ProtocolProperties properties;
/**
* 服务器 ID用于消息追踪全局唯一
*/
@@ -76,7 +77,7 @@ public class IotTcpProtocol implements IotProtocol {
*/
private final IotTcpFrameCodec frameCodec;
public IotTcpProtocol(ProtocolInstanceProperties properties) {
public IotTcpProtocol(ProtocolProperties properties) {
IotTcpConfig tcpConfig = properties.getTcp();
Assert.notNull(tcpConfig, "TCP 协议配置tcp不能为空");
Assert.notNull(tcpConfig.getCodec(), "TCP 拆包配置tcp.codec不能为空");
@@ -128,10 +129,11 @@ public class IotTcpProtocol implements IotProtocol {
.setTcpNoDelay(true)
.setReuseAddress(true)
.setIdleTimeout((int) (tcpConfig.getKeepAliveTimeoutMs() / 1000)); // 设置空闲超时
if (Boolean.TRUE.equals(tcpConfig.getSslEnabled())) {
IotGatewayProperties.SslConfig sslConfig = properties.getSsl();
if (sslConfig != null && Boolean.TRUE.equals(sslConfig.getSsl())) {
PemKeyCertOptions pemKeyCertOptions = new PemKeyCertOptions()
.setKeyPath(tcpConfig.getSslKeyPath())
.setCertPath(tcpConfig.getSslCertPath());
.setKeyPath(sslConfig.getSslKeyPath())
.setCertPath(sslConfig.getSslCertPath());
options.setSsl(true).setKeyCertOptions(pemKeyCertOptions);
}

View File

@@ -4,7 +4,7 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
import cn.iocoder.yudao.module.iot.core.enums.IotSerializeTypeEnum;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolInstanceProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolProperties;
import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol;
import cn.iocoder.yudao.module.iot.gateway.protocol.udp.handler.downstream.IotUdpDownstreamHandler;
import cn.iocoder.yudao.module.iot.gateway.protocol.udp.handler.downstream.IotUdpDownstreamSubscriber;
@@ -33,7 +33,7 @@ public class IotUdpProtocol implements IotProtocol {
/**
* 协议配置
*/
private final ProtocolInstanceProperties properties;
private final ProtocolProperties properties;
/**
* 服务器 ID用于消息追踪全局唯一
*/
@@ -70,7 +70,7 @@ public class IotUdpProtocol implements IotProtocol {
*/
private final IotMessageSerializer serializer;
public IotUdpProtocol(ProtocolInstanceProperties properties) {
public IotUdpProtocol(ProtocolProperties properties) {
IotUdpConfig udpConfig = properties.getUdp();
Assert.notNull(udpConfig, "UDP 协议配置udp不能为空");
this.properties = properties;

View File

@@ -35,20 +35,4 @@ public class IotWebSocketConfig {
@NotNull(message = "空闲超时时间不能为空")
private Integer idleTimeoutSeconds = 60;
/**
* 是否启用 SSLwss://
*/
@NotNull(message = "是否启用 SSL 不能为空")
private Boolean sslEnabled = false;
/**
* SSL 证书路径
*/
private String sslCertPath;
/**
* SSL 私钥路径
*/
private String sslKeyPath;
}

View File

@@ -6,7 +6,8 @@ import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
import cn.iocoder.yudao.module.iot.core.enums.IotSerializeTypeEnum;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolInstanceProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties;
import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolProperties;
import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol;
import cn.iocoder.yudao.module.iot.gateway.protocol.websocket.handler.downstream.IotWebSocketDownstreamSubscriber;
import cn.iocoder.yudao.module.iot.gateway.protocol.websocket.handler.downstream.IotWebSocketDownstreamHandler;
@@ -35,7 +36,7 @@ public class IotWebSocketProtocol implements IotProtocol {
/**
* 协议配置
*/
private final ProtocolInstanceProperties properties;
private final ProtocolProperties properties;
/**
* 服务器 ID用于消息追踪全局唯一
*/
@@ -71,7 +72,7 @@ public class IotWebSocketProtocol implements IotProtocol {
*/
private final IotMessageSerializer serializer;
public IotWebSocketProtocol(ProtocolInstanceProperties properties) {
public IotWebSocketProtocol(ProtocolProperties properties) {
Assert.notNull(properties, "协议实例配置不能为空");
Assert.notNull(properties.getWebsocket(), "WebSocket 协议配置websocket不能为空");
this.properties = properties;
@@ -120,10 +121,11 @@ public class IotWebSocketProtocol implements IotProtocol {
.setIdleTimeout(wsConfig.getIdleTimeoutSeconds())
.setMaxWebSocketFrameSize(wsConfig.getMaxFrameSize())
.setMaxWebSocketMessageSize(wsConfig.getMaxMessageSize());
if (Boolean.TRUE.equals(wsConfig.getSslEnabled())) {
IotGatewayProperties.SslConfig sslConfig = properties.getSsl();
if (sslConfig != null && Boolean.TRUE.equals(sslConfig.getSsl())) {
PemKeyCertOptions pemKeyCertOptions = new PemKeyCertOptions()
.setKeyPath(wsConfig.getSslKeyPath())
.setCertPath(wsConfig.getSslCertPath());
.setKeyPath(sslConfig.getSslKeyPath())
.setCertPath(sslConfig.getSslCertPath());
options.setSsl(true).setKeyCertOptions(pemKeyCertOptions);
}