diff --git a/cn-universal-framework/cn-universal-dm/src/main/java/cn/universal/dm/device/service/action/IoTDeviceActionBeforeService.java b/cn-universal-framework/cn-universal-dm/src/main/java/cn/universal/dm/device/service/action/IoTDeviceActionBeforeService.java index 00021708c555517c8910010bf7515b606a0b4216..1c86497dc954be02f737286571882ea717b4a086 100644 --- a/cn-universal-framework/cn-universal-dm/src/main/java/cn/universal/dm/device/service/action/IoTDeviceActionBeforeService.java +++ b/cn-universal-framework/cn-universal-dm/src/main/java/cn/universal/dm/device/service/action/IoTDeviceActionBeforeService.java @@ -30,16 +30,7 @@ public class IoTDeviceActionBeforeService implements IoTDeviceLifeCycle { @Override public void create(String productKey, String deviceId, DownRequest downRequest) { - // if (downRequest.getAppUnionId() != null) { - // IoTUser iotUser = IoTUser.builder().unionId(downRequest.getAppUnionId()).build(); - // IoTUser iotUser1 = iotUserMapper.selectOne(iotUser); - // if (iotUser1.getLicenseTotalAmount() == null) { - // throw new IoTException("设备接入数已用完"); - // } - // if (iotUser1.getLicense() <= 0) { - // throw new IoTException("设备接入数已用完"); - // } - // } + //TODO 这里可以限制用户接入数量 } @Override diff --git a/cn-universal-framework/cn-universal-notice/src/test/java/cn/universal/manager/notice/NoticeTest.java b/cn-universal-framework/cn-universal-notice/src/test/java/cn/universal/manager/notice/NoticeTest.java deleted file mode 100644 index 67317b4e0622f521cc62a34351ca867e693ba0c0..0000000000000000000000000000000000000000 --- a/cn-universal-framework/cn-universal-notice/src/test/java/cn/universal/manager/notice/NoticeTest.java +++ /dev/null @@ -1,109 +0,0 @@ -// package cn.universal.manager.notice; -// -// import cn.universal.manager.notice.model.NoticeSendChannel; -// import cn.universal.manager.notice.model.NoticeTemplate; -// import cn.universal.manager.notice.service.NoticeChannelService; -// import cn.universal.manager.notice.service.NoticeTemplateService; -// import cn.universal.manager.notice.util.TemplateUtil; -// import org.junit.jupiter.api.Test; -// import org.springframework.beans.factory.annotation.Autowired; -// import org.springframework.boot.test.context.SpringBootTest; -// -// import java.util.HashMap; -// import java.util.List; -// import java.util.Map; -// -// @SpringBootTest -// public class NoticeTest { -// -// @Autowired -// private NoticeChannelService noticeChannelService; -// -// @Autowired -// private NoticeTemplateService noticeTemplateService; -// -// @Test -// public void testChannelCRUD() { -// // 测试渠道CRUD操作 -// NoticeSendChannel channel = new NoticeSendChannel(); -// channel.setName("测试钉钉机器人"); -// channel.setChannelType("dingTalk"); -// channel.setConfig("{\"webhook\":\"https://test.com\",\"secret\":\"test\"}"); -// channel.setStatus("1"); -// channel.setRemark("测试渠道"); -// channel.setCreator("test"); -// -// // 保存 -// noticeChannelService.save(channel); -// System.out.println("保存渠道成功,ID: " + channel.getId()); -// -// // 查询 -// NoticeSendChannel saved = noticeChannelService.getById(channel.getId()); -// System.out.println("查询渠道: " + saved.getName()); -// -// // 搜索 -// List list = noticeChannelService.search("测试", "dingTalk", "1"); -// System.out.println("搜索到 " + list.size() + " 个渠道"); -// -// // 删除 -// noticeChannelService.delete(channel.getId()); -// System.out.println("删除渠道成功"); -// } -// -// @Test -// public void testTemplateCRUD() { -// // 测试模板CRUD操作 -// NoticeTemplate template = new NoticeTemplate(); -// template.setName("测试告警模板"); -// template.setChannelType("dingTalk"); -// template.setChannelId(1L); -// template.setContent("设备${deviceName}发生${alertLevel}级别告警:${alertMessage}"); -// template.setReceivers("[\"test_group\"]"); -// template.setStatus("1"); -// template.setRemark("测试模板"); -// template.setCreator("test"); -// -// // 保存 -// noticeTemplateService.save(template); -// System.out.println("保存模板成功,ID: " + template.getId()); -// -// // 查询 -// NoticeTemplate saved = noticeTemplateService.getById(template.getId()); -// System.out.println("查询模板: " + saved.getName()); -// -// // 搜索 -// List list = noticeTemplateService.search("测试", "dingTalk", "1"); -// System.out.println("搜索到 " + list.size() + " 个模板"); -// -// // 删除 -// noticeTemplateService.delete(template.getId()); -// System.out.println("删除模板成功"); -// } -// -// @Test -// public void testTemplateUtil() { -// // 测试模板工具类 -// String template = "设备${deviceName}发生${alertLevel}级别告警:${alertMessage},时间:${alertTime}"; -// -// Map params = new HashMap<>(); -// params.put("deviceName", "温度传感器001"); -// params.put("alertLevel", "严重"); -// params.put("alertMessage", "温度过高报警"); -// params.put("alertTime", "2024-01-15 14:30:25"); -// -// String result = TemplateUtil.replaceParams(template, params); -// System.out.println("模板替换结果: " + result); -// } -// -// @Test -// public void testTemplateTest() { -// // 测试模板测试功能 -// Map params = new HashMap<>(); -// params.put("deviceName", "温度传感器001"); -// params.put("alertLevel", "严重"); -// params.put("alertMessage", "温度过高报警"); -// params.put("alertTime", "2024-01-15 14:30:25"); -// -// noticeTemplateService.testTemplate(1L, "test_group", params); -// } -// } diff --git a/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/processor/topic/PassthroughProcessor.java b/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/processor/topic/PassthroughProcessor.java deleted file mode 100644 index f48d1593e438d51cfe7db0083fe83b94401a3bdc..0000000000000000000000000000000000000000 --- a/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/processor/topic/PassthroughProcessor.java +++ /dev/null @@ -1,323 +0,0 @@ -/// * -// * -// * Copyright (c) 2025, IoT-Universal. All Rights Reserved. -// * -// * @Description: 本文件由 Aleo 开发并拥有版权,未经授权严禁擅自商用、复制或传播。 -// * @Author: Aleo -// * @Email: wo8335224@gmail.com -// * @Wechat: outlookFil -// * -// * -// */ -// -// package cn.universal.protocol.mqtt.v2.processor.topic; -// -// import entity.cn.universal.protocol.mqtt.MQTTUPRequest; -// import processor.cn.universal.protocol.mqtt.MqttMessageProcessor; -// import topic.cn.universal.protocol.mqtt.MQTTTopicManager; -// import topic.cn.universal.protocol.mqtt.MQTTTopicType; -// import lombok.extern.slf4j.Slf4j; -// import org.springframework.beans.factory.annotation.Autowired; -// import org.springframework.stereotype.Component; -// -/// ** -// * 透传处理器 -// *

-// * 专门处理透传级MQTT消息: -// * - 透传协议上行 ($thing/up/${productKey}/${deviceId}) -// * - 透传协议下行 ($thing/down/${productKey}/${deviceId}) -// *

-// * 透传消息不做业务逻辑解析,直接转发给相应的处理链 -// * -// * @Author Aleo -// * @version 1.0 -// * @since 2025/1/20 -// */ -// @Slf4j(topic = "mqtt") -// @Component -// public class PassthroughProcessor implements MqttMessageProcessor { -// -// @Autowired -// private MQTTTopicManager topicManager; -// -// @Override -// public String getName() { -// return "透传处理器"; -// } -// -// @Override -// public String getDescription() { -// return "处理透传协议上行和下行消息,不做业务逻辑解析"; -// } -// -// @Override -// public int getOrder() { -// return 300; // 透传处理优先级较低 -// } -// -// @Override -// public boolean supports(MQTTUPRequest request) { -// MQTTTopicManager.TopicInfo topicInfo = topicManager.extractTopicInfo(request.getTopic()); -// return topicInfo.isValid() && topicInfo.getCategory() == -// MqttConstant.TopicCategory.PASSTHROUGH; -// } -// -// @Override -// public ProcessorResult process(MQTTUPRequest request) { -// try { -// MQTTTopicManager.TopicInfo topicInfo = -// topicManager.extractTopicInfo(request.getTopic()); -// -// log.debug("[{}] 开始处理透传消息 - 类型: {}, 设备: {}", -// getName(), topicInfo.getTopicType(), topicInfo.getDeviceUniqueId()); -// -// // 根据透传消息类型分发处理 -// switch (topicInfo.getTopicType()) { -// case PASSTHROUGH_UP: -// return processUpstreamPassthrough(request, topicInfo); -// -// case PASSTHROUGH_DOWN: -// return processDownstreamPassthrough(request, topicInfo); -// -// default: -// log.warn("[{}] 不支持的透传类型: {}", getName(), topicInfo.getTopicType()); -// return ProcessorResult.CONTINUE; -// } -// -// } catch (Exception e) { -// log.error("[{}] 透传消息处理异常: ", getName(), e); -// return ProcessorResult.ERROR; -// } -// } -// -// /** -// * 处理上行透传消息 -// */ -// private ProcessorResult processUpstreamPassthrough(MQTTUPRequest request, -// MQTTTopicManager.TopicInfo topicInfo) { -// try { -// byte[] rawData = request.getMessageContentAsBytes(); -// String payload = request.getMessageContentAsString(); -// -// log.info("[{}] 处理上行透传 - 设备: {}, 数据长度: {}字节", -// getName(), topicInfo.getDeviceUniqueId(), rawData.length); -// -// // 设置上下文信息 -// request.setContextValue("messageType", "PASSTHROUGH_UPSTREAM"); -// request.setContextValue("topicType", "PASSTHROUGH_UP"); -// request.setContextValue("dataLength", rawData.length); -// request.setContextValue("rawData", rawData); -// -// // 透传数据验证 -// if (validatePassthroughData(rawData)) { -// // 记录数据统计 -// incrementUpstreamCounter(topicInfo.getProductKey(), rawData.length); -// -// // 标记为透传数据,供后续处理器识别 -// request.setContextValue("isPassthrough", true); -// request.setContextValue("needDecode", true); // 标记需要解码 -// -// log.debug("[{}] 上行透传处理成功 - 设备: {}, 数据: {}", -// getName(), topicInfo.getDeviceUniqueId(), payload); -// return ProcessorResult.CONTINUE; -// } else { -// log.warn("[{}] 透传数据验证失败 - 设备: {}", getName(), topicInfo.getDeviceUniqueId()); -// request.setContextValue("validationError", "透传数据格式不正确"); -// return ProcessorResult.CONTINUE; -// } -// -// } catch (Exception e) { -// log.error("[{}] 上行透传处理异常 - 设备: {}, 异常: ", -// getName(), topicInfo.getDeviceUniqueId(), e); -// return ProcessorResult.ERROR; -// } -// } -// -// /** -// * 处理下行透传消息 -// */ -// private ProcessorResult processDownstreamPassthrough(MQTTUPRequest request, -// MQTTTopicManager.TopicInfo -// topicInfo) { -// try { -// byte[] rawData = request.getMessageContentAsBytes(); -// String payload = request.getMessageContentAsString(); -// -// log.info("[{}] 处理下行透传 - 设备: {}, 数据长度: {}字节", -// getName(), topicInfo.getDeviceUniqueId(), rawData.length); -// -// // 设置上下文信息 -// request.setContextValue("messageType", "PASSTHROUGH_DOWNSTREAM"); -// request.setContextValue("topicType", "PASSTHROUGH_DOWN"); -// request.setContextValue("dataLength", rawData.length); -// request.setContextValue("rawData", rawData); -// -// // 透传数据验证 -// if (validatePassthroughData(rawData)) { -// // 记录数据统计 -// incrementDownstreamCounter(topicInfo.getProductKey(), rawData.length); -// -// // 标记为透传数据 -// request.setContextValue("isPassthrough", true); -// request.setContextValue("needEncode", true); // 标记需要编码 -// -// // 下行透传可能需要回复确认 -// if (needAcknowledge(rawData)) { -// request.setContextValue("needReply", true); -// request.setContextValue("replyTopic", buildAckTopic(topicInfo)); -// } -// -// log.debug("[{}] 下行透传处理成功 - 设备: {}, 数据: {}", -// getName(), topicInfo.getDeviceUniqueId(), payload); -// return ProcessorResult.CONTINUE; -// } else { -// log.warn("[{}] 透传数据验证失败 - 设备: {}", getName(), topicInfo.getDeviceUniqueId()); -// request.setContextValue("validationError", "透传数据格式不正确"); -// return ProcessorResult.CONTINUE; -// } -// -// } catch (Exception e) { -// log.error("[{}] 下行透传处理异常 - 设备: {}, 异常: ", -// getName(), topicInfo.getDeviceUniqueId(), e); -// return ProcessorResult.ERROR; -// } -// } -// -// /** -// * 验证透传数据 -// */ -// private boolean validatePassthroughData(byte[] data) { -// // 基本验证:数据不能为空 -// if (data == null || data.length == 0) { -// return false; -// } -// -// // 数据长度限制(例如不超过64KB) -// if (data.length > 64 * 1024) { -// log.warn("[{}] 透传数据过大: {}字节", getName(), data.length); -// return false; -// } -// -// return true; -// } -// -// /** -// * 检查是否需要确认回复 -// */ -// private boolean needAcknowledge(byte[] data) { -// // 透传数据的确认逻辑可以根据协议定制 -// // 这里简单判断:如果数据以特定字节开头,则需要确认 -// return data.length > 0 && (data[0] & 0x80) != 0; // 最高位为1表示需要确认 -// } -// -// /** -// * 构建确认回复主题 -// */ -// private String buildAckTopic(MQTTTopicManager.TopicInfo topicInfo) { -// // 透传确认主题:$thing/up/ack/${productKey}/${deviceId} -// return "$thing/up/ack/" + topicInfo.getProductKey() + "/" + topicInfo.getDeviceId(); -// } -// -// /** -// * 增加上行计数器 -// */ -// private void incrementUpstreamCounter(String productKey, int dataLength) { -// // TODO: 实现上行透传统计逻辑 -// log.debug("[{}] 上行透传计数器增加 - 产品: {}, 数据长度: {}字节", -// getName(), productKey, dataLength); -// } -// -// /** -// * 增加下行计数器 -// */ -// private void incrementDownstreamCounter(String productKey, int dataLength) { -// // TODO: 实现下行透传统计逻辑 -// log.debug("[{}] 下行透传计数器增加 - 产品: {}, 数据长度: {}字节", -// getName(), productKey, dataLength); -// } -// -// /** -// * 尝试解析透传数据的类型 -// */ -// private String parsePassthroughDataType(byte[] data) { -// if (data == null || data.length == 0) { -// return "UNKNOWN"; -// } -// -// // 根据数据特征判断类型 -// if (data.length >= 2) { -// int header = ((data[0] & 0xFF) << 8) | (data[1] & 0xFF); -// -// switch (header & 0xF000) { -// case 0x1000: -// return "SENSOR_DATA"; -// case 0x2000: -// return "CONTROL_CMD"; -// case 0x3000: -// return "CONFIG_DATA"; -// default: -// return "RAW_DATA"; -// } -// } -// -// return "RAW_DATA"; -// } -// -// /** -// * 提取设备信息(如果透传数据中包含) -// */ -// private void extractDeviceInfo(MQTTUPRequest request, byte[] data) { -// try { -// // 尝试从透传数据中提取设备相关信息 -// String dataType = parsePassthroughDataType(data); -// request.setContextValue("passthroughDataType", dataType); -// -// // 如果是传感器数据,可能包含时间戳等信息 -// if ("SENSOR_DATA".equals(dataType) && data.length >= 8) { -// // 假设后4个字节是时间戳 -// long timestamp = 0; -// for (int i = 4; i < 8; i++) { -// timestamp = (timestamp << 8) | (data[i] & 0xFF); -// } -// request.setContextValue("dataTimestamp", timestamp); -// } -// -// } catch (Exception e) { -// log.debug("[{}] 设备信息提取失败: ", getName(), e); -// } -// } -// -// @Override -// public boolean preCheck(MQTTUPRequest request) { -// return supports(request); -// } -// -// @Override -// public void postProcess(MQTTUPRequest request, ProcessorResult result) { -// if (result == ProcessorResult.CONTINUE) { -// // 透传处理完成后,提取额外的设备信息 -// byte[] data = (byte[]) request.getContextValue("rawData"); -// if (data != null) { -// extractDeviceInfo(request, data); -// } -// -// log.debug("[{}] 透传处理完成 - 设备: {}", getName(), request.getDeviceUniqueId()); -// } else { -// log.warn("[{}] 透传处理异常 - 设备: {}, 结果: {}", -// getName(), request.getDeviceUniqueId(), result); -// } -// } -// -// @Override -// public void onError(MQTTUPRequest request, Exception e) { -// log.error("[{}] 透传处理器异常 - 设备: {}, 异常: ", -// getName(), request.getDeviceUniqueId(), e); -// request.setError("透传处理失败: " + e.getMessage()); -// } -// -// @Override -// public int getPriority() { -// // 透传处理优先级中等 -// return 5; -// } -// } diff --git a/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/processor/topic/ThingModelProcessor.java b/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/processor/topic/ThingModelProcessor.java deleted file mode 100644 index 11478c1b6c42094e864d3f826aced12e6ae0c6b0..0000000000000000000000000000000000000000 --- a/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/processor/topic/ThingModelProcessor.java +++ /dev/null @@ -1,338 +0,0 @@ -/// * -// * -// * Copyright (c) 2025, IoT-Universal. All Rights Reserved. -// * -// * @Description: 本文件由 Aleo 开发并拥有版权,未经授权严禁擅自商用、复制或传播。 -// * @Author: Aleo -// * @Email: wo8335224@gmail.com -// * @Wechat: outlookFil -// * -// * -// */ -// -// package cn.universal.protocol.mqtt.v2.processor.topic; -// -// import entity.cn.universal.protocol.mqtt.MQTTUPRequest; -// import processor.cn.universal.protocol.mqtt.MqttMessageProcessor; -// import topic.cn.universal.protocol.mqtt.MQTTTopicManager; -// import topic.cn.universal.protocol.mqtt.MQTTTopicType; -// import com.fasterxml.jackson.databind.JsonNode; -// import com.fasterxml.jackson.databind.ObjectMapper; -// import lombok.extern.slf4j.Slf4j; -// import org.springframework.beans.factory.annotation.Autowired; -// import org.springframework.stereotype.Component; -// -/// ** -// * 物模型处理器 -// *

-// * 专门处理物模型相关的MQTT消息: -// * - 属性上报 ($thing/up/property/${productKey}/${deviceId}) -// * - 事件上报 ($thing/up/event/${productKey}/${deviceId}) -// * - 下行控制 ($thing/down/${productKey}/${deviceId}) -// * -// * @Author Aleo -// * @version 1.0 -// * @since 2025/1/20 -// */ -// @Slf4j(topic = "mqtt") -// @Component -// public class ThingModelProcessor implements MqttMessageProcessor { -// -// @Autowired -// private MQTTTopicManager topicManager; -// -// private final ObjectMapper objectMapper = new ObjectMapper(); -// -// @Override -// public String getName() { -// return "物模型处理器"; -// } -// -// @Override -// public String getDescription() { -// return "处理设备属性上报、事件上报和下行控制消息"; -// } -// -// @Override -// public int getOrder() { -// return 100; // 物模型处理优先级较高 -// } -// -// @Override -// public boolean supports(MQTTUPRequest request) { -// MQTTTopicManager.TopicInfo topicInfo = topicManager.extractTopicInfo(request.getTopic()); -// return topicInfo.isValid() && topicInfo.getCategory() == -// MqttConstant.TopicCategory.THING_MODEL; -// } -// -// @Override -// public ProcessorResult process(MQTTUPRequest request) { -// try { -// MQTTTopicManager.TopicInfo topicInfo = -// topicManager.extractTopicInfo(request.getTopic()); -// -// log.debug("[{}] 开始处理物模型消息 - 类型: {}, 设备: {}", -// getName(), topicInfo.getTopicType(), topicInfo.getDeviceUniqueId()); -// -// // 根据具体的物模型类型分发处理 -// switch (topicInfo.getTopicType()) { -// case THING_PROPERTY_UP: -// return processPropertyReport(request, topicInfo); -// -// case THING_EVENT_UP: -// return processEventReport(request, topicInfo); -// -// case THING_DOWN: -// return processDownstreamControl(request, topicInfo); -// -// default: -// log.warn("[{}] 不支持的物模型类型: {}", getName(), topicInfo.getTopicType()); -// return ProcessorResult.CONTINUE; -// } -// -// } catch (Exception e) { -// log.error("[{}] 物模型消息处理异常: ", getName(), e); -// return ProcessorResult.ERROR; -// } -// } -// -// /** -// * 处理属性上报 -// */ -// private ProcessorResult processPropertyReport(MQTTUPRequest request, -// MQTTTopicManager.TopicInfo topicInfo) { -// try { -// String payload = request.getMessageContentAsString(); -// JsonNode propertyData = objectMapper.readTree(payload); -// -// log.info("[{}] 处理属性上报 - 设备: {}, 属性数量: {}", -// getName(), topicInfo.getDeviceUniqueId(), propertyData.size()); -// -// // 设置上下文信息 -// request.setContextValue("messageType", "PROPERTY_REPORT"); -// request.setContextValue("topicType", "THING_PROPERTY_UP"); -// request.setContextValue("propertyCount", propertyData.size()); -// -// // 解析和验证属性数据 -// if (validatePropertyData(propertyData)) { -// // 存储属性数据到上下文 -// request.setContextValue("propertyData", propertyData); -// -// // 记录处理统计 -// incrementPropertyCounter(topicInfo.getProductKey()); -// -// log.debug("[{}] 属性上报处理成功 - 设备: {}", getName(), topicInfo.getDeviceUniqueId()); -// return ProcessorResult.CONTINUE; -// } else { -// log.warn("[{}] 属性数据验证失败 - 设备: {}", getName(), topicInfo.getDeviceUniqueId()); -// request.setContextValue("validationError", "属性数据格式不正确"); -// return ProcessorResult.CONTINUE; -// } -// -// } catch (Exception e) { -// log.error("[{}] 属性上报处理异常 - 设备: {}, 异常: ", -// getName(), topicInfo.getDeviceUniqueId(), e); -// return ProcessorResult.ERROR; -// } -// } -// -// /** -// * 处理事件上报 -// */ -// private ProcessorResult processEventReport(MQTTUPRequest request, MQTTTopicManager.TopicInfo -// topicInfo) { -// try { -// String payload = request.getMessageContentAsString(); -// JsonNode eventData = objectMapper.readTree(payload); -// -// log.info("[{}] 处理事件上报 - 设备: {}, 事件: {}", -// getName(), topicInfo.getDeviceUniqueId(), -// eventData.path("eventType").asText("unknown")); -// -// // 设置上下文信息 -// request.setContextValue("messageType", "EVENT_REPORT"); -// request.setContextValue("topicType", "THING_EVENT_UP"); -// request.setContextValue("eventType", eventData.path("eventType").asText()); -// request.setContextValue("eventLevel", eventData.path("level").asText("INFO")); -// -// // 解析事件数据 -// if (validateEventData(eventData)) { -// // 存储事件数据到上下文 -// request.setContextValue("eventData", eventData); -// -// // 检查是否需要告警 -// String eventLevel = eventData.path("level").asText("INFO"); -// if ("ERROR".equals(eventLevel) || "CRITICAL".equals(eventLevel)) { -// request.setContextValue("needAlert", true); -// log.warn("[{}] 高级别事件上报 - 设备: {}, 级别: {}", -// getName(), topicInfo.getDeviceUniqueId(), eventLevel); -// } -// -// // 记录处理统计 -// incrementEventCounter(topicInfo.getProductKey(), eventLevel); -// -// log.debug("[{}] 事件上报处理成功 - 设备: {}", getName(), topicInfo.getDeviceUniqueId()); -// return ProcessorResult.CONTINUE; -// } else { -// log.warn("[{}] 事件数据验证失败 - 设备: {}", getName(), topicInfo.getDeviceUniqueId()); -// request.setContextValue("validationError", "事件数据格式不正确"); -// return ProcessorResult.CONTINUE; -// } -// -// } catch (Exception e) { -// log.error("[{}] 事件上报处理异常 - 设备: {}, 异常: ", -// getName(), topicInfo.getDeviceUniqueId(), e); -// return ProcessorResult.ERROR; -// } -// } -// -// /** -// * 处理下行控制 -// */ -// private ProcessorResult processDownstreamControl(MQTTUPRequest request, -// MQTTTopicManager.TopicInfo topicInfo) { -// try { -// String payload = request.getMessageContentAsString(); -// JsonNode controlData = objectMapper.readTree(payload); -// -// log.info("[{}] 处理下行控制 - 设备: {}, 命令: {}", -// getName(), topicInfo.getDeviceUniqueId(), -// controlData.path("command").asText("unknown")); -// -// // 设置上下文信息 -// request.setContextValue("messageType", "DOWNSTREAM_CONTROL"); -// request.setContextValue("topicType", "THING_DOWN"); -// request.setContextValue("command", controlData.path("command").asText()); -// request.setContextValue("commandId", controlData.path("commandId").asText()); -// -// // 解析控制指令 -// if (validateControlData(controlData)) { -// // 存储控制数据到上下文 -// request.setContextValue("controlData", controlData); -// -// // 记录控制指令 -// String command = controlData.path("command").asText(); -// log.info("[{}] 下行控制指令 - 设备: {}, 命令: {}", -// getName(), topicInfo.getDeviceUniqueId(), command); -// -// // 记录处理统计 -// incrementControlCounter(topicInfo.getProductKey(), command); -// -// // 标记需要回复确认 -// request.setContextValue("needReply", true); -// request.setContextValue("replyTopic", buildReplyTopic(topicInfo)); -// -// log.debug("[{}] 下行控制处理成功 - 设备: {}", getName(), topicInfo.getDeviceUniqueId()); -// return ProcessorResult.CONTINUE; -// } else { -// log.warn("[{}] 控制数据验证失败 - 设备: {}", getName(), topicInfo.getDeviceUniqueId()); -// request.setContextValue("validationError", "控制数据格式不正确"); -// return ProcessorResult.CONTINUE; -// } -// -// } catch (Exception e) { -// log.error("[{}] 下行控制处理异常 - 设备: {}, 异常: ", -// getName(), topicInfo.getDeviceUniqueId(), e); -// return ProcessorResult.ERROR; -// } -// } -// -// /** -// * 验证属性数据格式 -// */ -// private boolean validatePropertyData(JsonNode propertyData) { -// // 基本验证:必须是对象类型且非空 -// if (!propertyData.isObject() || propertyData.size() == 0) { -// return false; -// } -// -// // 验证每个属性是否包含必要字段 -// return propertyData.fields().hasNext(); -// } -// -// /** -// * 验证事件数据格式 -// */ -// private boolean validateEventData(JsonNode eventData) { -// // 基本验证:必须包含eventType字段 -// if (!eventData.isObject() || !eventData.has("eventType")) { -// return false; -// } -// -// String eventType = eventData.path("eventType").asText(); -// return eventType != null && !eventType.trim().isEmpty(); -// } -// -// /** -// * 验证控制数据格式 -// */ -// private boolean validateControlData(JsonNode controlData) { -// // 基本验证:必须包含command字段 -// if (!controlData.isObject() || !controlData.has("command")) { -// return false; -// } -// -// String command = controlData.path("command").asText(); -// return command != null && !command.trim().isEmpty(); -// } -// -// /** -// * 构建回复主题 -// */ -// private String buildReplyTopic(MQTTTopicManager.TopicInfo topicInfo) { -// // 下行控制的回复主题:$thing/up/reply/${productKey}/${deviceId} -// return "$thing/up/reply/" + topicInfo.getProductKey() + "/" + topicInfo.getDeviceId(); -// } -// -// /** -// * 增加属性计数器 -// */ -// private void incrementPropertyCounter(String productKey) { -// // TODO: 实现属性统计逻辑 -// log.debug("[{}] 属性计数器增加 - 产品: {}", getName(), productKey); -// } -// -// /** -// * 增加事件计数器 -// */ -// private void incrementEventCounter(String productKey, String eventLevel) { -// // TODO: 实现事件统计逻辑 -// log.debug("[{}] 事件计数器增加 - 产品: {}, 级别: {}", getName(), productKey, eventLevel); -// } -// -// /** -// * 增加控制计数器 -// */ -// private void incrementControlCounter(String productKey, String command) { -// // TODO: 实现控制统计逻辑 -// log.debug("[{}] 控制计数器增加 - 产品: {}, 命令: {}", getName(), productKey, command); -// } -// -// @Override -// public boolean preCheck(MQTTUPRequest request) { -// return supports(request); -// } -// -// @Override -// public void postProcess(MQTTUPRequest request, ProcessorResult result) { -// if (result == ProcessorResult.CONTINUE) { -// log.debug("[{}] 物模型处理完成 - 设备: {}", getName(), request.getDeviceUniqueId()); -// } else { -// log.warn("[{}] 物模型处理异常 - 设备: {}, 结果: {}", -// getName(), request.getDeviceUniqueId(), result); -// } -// } -// -// @Override -// public void onError(MQTTUPRequest request, Exception e) { -// log.error("[{}] 物模型处理器异常 - 设备: {}, 异常: ", -// getName(), request.getDeviceUniqueId(), e); -// request.setError("物模型处理失败: " + e.getMessage()); -// } -// -// @Override -// public int getPriority() { -// // 物模型处理优先级较高 -// return 10; -// } -// } diff --git a/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/third/ThirdMQTTFacade.java b/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/third/ThirdMQTTFacade.java deleted file mode 100644 index e9f3f8375e6395b115b0a1ee3bbf93b04eb3f765..0000000000000000000000000000000000000000 --- a/cn-universal-protocol/cn-universal-mqtt-protocol/src/main/java/cn/universal/mqtt/protocol/third/ThirdMQTTFacade.java +++ /dev/null @@ -1,445 +0,0 @@ -/// * -// * -// * Copyright (c) 2025, IoT-Universal. All Rights Reserved. -// * -// * @Description: 本文件由 Aleo 开发并拥有版权,未经授权严禁擅自商用、复制或传播。 -// * @Author: Aleo -// * @Email: wo8335224@gmail.com -// * @Wechat: outlookFil -// * -// * -// */ -// -// package cn.universal.protocol.mqtt.v2.third; -// -// import entity.cn.universal.protocol.mqtt.MQTTProductConfig; -// import entity.cn.universal.protocol.mqtt.MQTTPublishMessage; -// import metrics.cn.universal.protocol.mqtt.MqttMetricsSnapshot; -// import java.util.Map; -// import lombok.extern.slf4j.Slf4j; -// -/// ** -// * MQTT 主服务类 -// *

-// * 提供MQTT消息服务能力 管理MQTT服务器、处理器链、指标收集等核心功能 -// * -// * @Author Aleo -// * @version 3.0 -// * @since 2025/1/20 -// */ -// @Slf4j(topic = "mqtt") -// public class ThirdMQTTFacade { -// -// -// // 服务状态 -// private volatile boolean initialized = false; -// private volatile boolean running = false; -// -// -// public String name() { -// return "MQTT"; -// } -// -// public String version() { -// return "3.0.0"; -// } -// -// public String description() { -// return "MQTT消息服务,支持MQTT协议的设备接入和消息处理"; -// } -// -// public boolean isEnabled() { -// return true; -// } -// -// public boolean isRunning() { -// return running; -// } -// -// /** -// * 初始化服务 -// */ -// public synchronized boolean initialize() { -// if (initialized) { -// log.warn("[THIRD_MQTT] 服务已初始化,无需重复初始化"); -// return true; -// } -// -// try { -// log.info("[THIRD_MQTT] 开始初始化MQTT服务..."); -// -// // 1. 检查依赖组件 -// if (!checkDependencies()) { -// log.error("[THIRD_MQTT] 依赖组件检查失败"); -// return false; -// } -// -// // 2. 服务器管理器会在PostConstruct中自动初始化 -// // 无需手动启动,等待初始化完成即可 -// -// // 3. 验证处理器链 -// if (!validateProcessorChain()) { -// log.error("[THIRD_MQTT] 处理器链验证失败"); -// return false; -// } -// -// initialized = true; -// running = true; -// -// // 4. 输出初始化信息 -// logInitializationInfo(); -// -// log.info("[THIRD_MQTT] MQTT服务初始化成功"); -// return true; -// -// } catch (Exception e) { -// log.error("[THIRD_MQTT] MQTT服务初始化失败: ", e); -// return false; -// } -// } -// -// /** -// * 启动服务 -// */ -// public synchronized boolean start() { -// if (!initialized) { -// return initialize(); -// } -// -// if (running) { -// log.warn("[THIRD_MQTT] 服务已在运行中"); -// return true; -// } -// -// try { -// log.info("[THIRD_MQTT] 启动MQTT服务..."); -// -// // 重新加载和启动所有客户端 -// serverManager.loadAndStartAllClients(); -// running = true; -// log.info("[THIRD_MQTT] MQTT服务启动成功"); -// return true; -// -// } catch (Exception e) { -// log.error("[THIRD_MQTT] MQTT服务启动异常: ", e); -// return false; -// } -// } -// -// /** -// * 停止服务 -// */ -// public synchronized boolean stop() { -// if (!running) { -// log.warn("[THIRD_MQTT] 服务未在运行中"); -// return true; -// } -// -// try { -// log.info("[THIRD_MQTT] 停止MQTT服务..."); -// -// // 调用destroy方法来停止所有客户端 -// serverManager.destroy(); -// running = false; -// log.info("[THIRD_MQTT] MQTT服务停止成功"); -// return true; -// -// } catch (Exception e) { -// log.error("[THIRD_MQTT] MQTT服务停止异常: ", e); -// return false; -// } -// } -// -// /** -// * 重启服务 -// */ -// public boolean restart() { -// log.info("[THIRD_MQTT] 重启MQTT服务..."); -// return stop() && start(); -// } -// -// /** -// * 主动发送消息 -// */ -// public boolean sendMessage(String productKey, String deviceId, String topic, String payload) { -// return sendMessage(productKey, deviceId, topic, payload, 1, false); -// } -// -// /** -// * 主动发送消息(完整参数) -// */ -// public boolean sendMessage(String productKey, String deviceId, String topic, String payload, -// int qos, boolean retained) { -// try { -// if (!running) { -// log.warn("[THIRD_MQTT] 服务未运行,无法发送消息"); -// return false; -// } -// -// // 构建发布消息 -// MQTTPublishMessage message = MQTTPublishMessage.builder().topic(topic) -// .content(payload).qos(qos).retained(retained).productKey(productKey) -// .deviceId(deviceId).messageType("API_SEND").build(); -// -// // 发送消息 -// boolean success = serverManager.publishMessage(productKey, message); -// -// if (success) { -// log.debug("[THIRD_MQTT] API发送消息成功 - 产品: {}, 设备: {}, 主题: {}", productKey, -// deviceId, topic); -// } else { -// log.warn("[THIRD_MQTT] API发送消息失败 - 产品: {}, 设备: {}, 主题: {}", productKey, -// deviceId, topic); -// } -// -// return success; -// -// } catch (Exception e) { -// log.error("[THIRD_MQTT] API发送消息异常 - 产品: {}, 设备: {}, 主题: {}, 异常: ", productKey, -// deviceId, topic, e); -// return false; -// } -// } -// -// /** -// * 添加产品配置 -// */ -// public boolean addProductConfig(MQTTProductConfig config) { -// try { -// // 重构后通过重新加载配置来添加产品 -// serverManager.reloadAllConfigs(); -// log.info("[THIRD_MQTT] 添加产品配置成功: {}", config.getProductKey()); -// return true; -// } catch (Exception e) { -// log.error("[THIRD_MQTT] 添加产品配置异常: ", e); -// return false; -// } -// } -// -// /** -// * 移除产品配置 -// */ -// public boolean removeProductConfig(String productKey) { -// try { -// // 停止指定产品的客户端 -// boolean success = serverManager.stopMqttClient(productKey); -// if (success) { -// log.info("[THIRD_MQTT] 移除产品配置成功: {}", productKey); -// } else { -// log.warn("[THIRD_MQTT] 移除产品配置失败: {}", productKey); -// } -// return success; -// } catch (Exception e) { -// log.error("[THIRD_MQTT] 移除产品配置异常: ", e); -// return false; -// } -// } -// -// /** -// * 重新加载配置 -// */ -// public boolean reloadConfigs() { -// try { -// log.info("[THIRD_MQTT] 重新加载配置..."); -// -// // 使用新的配置服务重新加载配置 -// serverManager.reloadAllConfigs(); -// -// Map configs = configService.loadAllConfigs(); -// log.info("[THIRD_MQTT] 配置重新加载完成,配置数: {}", configs.size()); -// return true; -// -// } catch (Exception e) { -// log.error("[THIRD_MQTT] 重新加载配置失败: ", e); -// return false; -// } -// } -// -// /** -// * 获取服务状态 -// */ -// public Map getStatus() { -// Map status = new java.util.HashMap<>(); -// -// status.put("serviceName", name()); -// status.put("version", version()); -// status.put("initialized", initialized); -// status.put("running", running); -// status.put("serverManagerStarted", isServerManagerStarted()); -// status.put("processorCount", processorChain.getProcessorCount()); -// status.put("enabledProcessorCount", processorChain.getEnabledProcessorCount()); -// -// return status; -// } -// -// /** -// * 检查服务器管理器是否启动 -// */ -// private boolean isServerManagerStarted() { -// try { -// // 通过检查活跃连接数来判断是否启动 -// int activeCount = serverManager.getActiveConnectionCount(); -// return activeCount >= 0; // 如果能获取到连接数,说明已启动 -// } catch (Exception e) { -// return false; -// } -// } -// -// /** -// * 获取指标快照 -// */ -// public MqttMetricsSnapshot getMetricsSnapshot() { -// return metricsCollector.getSnapshot(); -// } -// -// /** -// * 获取详细统计信息 -// */ -// public String getDetailedStatistics() { -// StringBuilder stats = new StringBuilder(); -// -// // 服务基础信息 -// stats.append("=== MQTT 服务信息 ===\n"); -// stats.append("服务名称: ").append(name()).append("\n"); -// stats.append("版本: ").append(version()).append("\n"); -// stats.append("描述: ").append(description()).append("\n"); -// stats.append("初始化状态: ").append(initialized ? "已初始化" : "未初始化").append("\n"); -// stats.append("运行状态: ").append(running ? "运行中" : "已停止").append("\n"); -// -// // 处理器链信息 -// stats.append("\n").append(processorChain.getStatistics()).append("\n"); -// -// // 服务器管理器信息 -// stats.append(serverManager.getStatistics()).append("\n"); -// -// // 指标信息 -// stats.append(metricsCollector.getDetailedStatistics()); -// -// return stats.toString(); -// } -// -// /** -// * 重置指标 -// */ -// public void resetMetrics() { -// metricsCollector.reset(); -// log.info("[THIRD_MQTT] 指标已重置"); -// } -// -// /** -// * 检查依赖组件 -// */ -// private boolean checkDependencies() { -// try { -// // 检查核心组件是否存在 -// if (serverManager == null) { -// log.error("[THIRD_MQTT] MqttServerManager未注入"); -// return false; -// } -// -// if (processorChain == null) { -// log.error("[THIRD_MQTT] MqttProcessorChain未注入"); -// return false; -// } -// -// if (metricsCollector == null) { -// log.error("[THIRD_MQTT] MqttMetricsCollector未注入"); -// return false; -// } -// -// if (configService == null) { -// log.error("[THIRD_MQTT] MqttConfigService未注入"); -// return false; -// } -// -// log.debug("[THIRD_MQTT] 依赖组件检查通过"); -// return true; -// -// } catch (Exception e) { -// log.error("[THIRD_MQTT] 依赖组件检查异常: ", e); -// return false; -// } -// } -// -// /** -// * 验证处理器链 -// */ -// private boolean validateProcessorChain() { -// try { -// int processorCount = processorChain.getProcessorCount(); -// if (processorCount == 0) { -// log.warn("[THIRD_MQTT] 处理器链中没有处理器"); -// return false; -// } -// -// long enabledCount = processorChain.getEnabledProcessorCount(); -// if (enabledCount == 0) { -// log.warn("[THIRD_MQTT] 处理器链中没有启用的处理器"); -// return false; -// } -// -// if (!processorChain.isHealthy()) { -// log.warn("[THIRD_MQTT] 处理器链健康检查失败"); -// return false; -// } -// -// log.debug("[THIRD_MQTT] 处理器链验证通过,总处理器: {}, 启用处理器: {}", processorCount, -// enabledCount); -// return true; -// -// } catch (Exception e) { -// log.error("[THIRD_MQTT] 处理器链验证异常: ", e); -// return false; -// } -// } -// -// /** -// * 输出初始化信息 -// */ -// private void logInitializationInfo() { -// log.info("[THIRD_MQTT] =========================================="); -// log.info("[THIRD_MQTT] MQTT 服务初始化信息"); -// log.info("[THIRD_MQTT] 服务名称: {}", name()); -// log.info("[THIRD_MQTT] 版本: {}", version()); -// log.info("[THIRD_MQTT] 描述: {}", description()); -// log.info("[THIRD_MQTT] 处理器数量: {}", processorChain.getProcessorCount()); -// log.info("[THIRD_MQTT] 启用处理器: {}", processorChain.getEnabledProcessorCount()); -// log.info("[THIRD_MQTT] 处理器列表: {}", processorChain.getProcessorNames()); -// log.info("[THIRD_MQTT] 配置产品数: {}", configService.getTotalEnabledProductCount()); -// log.info("[THIRD_MQTT] =========================================="); -// } -// -// /** -// * 健康检查 -// */ -// public boolean healthCheck() { -// try { -// // 检查服务状态 -// if (!initialized || !running) { -// return false; -// } -// -// // 检查服务器管理器 -// if (!isServerManagerStarted()) { -// return false; -// } -// -// // 检查处理器链 -// if (!processorChain.isHealthy()) { -// return false; -// } -// -// // 检查指标状态 -// MqttMetricsSnapshot snapshot = metricsCollector.getSnapshot(); -// if (snapshot.getHealthStatus() == MqttMetricsSnapshot.HealthStatus.CRITICAL) { -// return false; -// } -// -// return true; -// -// } catch (Exception e) { -// log.error("[THIRD_MQTT] 健康检查异常: ", e); -// return false; -// } -// } -// } diff --git a/cn-universal-web/README.md b/cn-universal-web/README.md deleted file mode 100644 index 850771ebd045ff7d1423883ce2d1ce3fccc56197..0000000000000000000000000000000000000000 --- a/cn-universal-web/README.md +++ /dev/null @@ -1,368 +0,0 @@ -# cn-universal-web 模块 - -## 概述 - -`cn-universal-web` 是IoT Universal平台的核心Web模块,提供RESTful API接口和Web服务。该模块基于Spring -Boot -3.x构建,集成了安全认证、设备管理、位置服务等核心功能。 - -## 模块结构 - -``` -cn-universal-web/ -├── src/main/java/cn/universal/ -│ ├── CnUniversalIoTApplication.java # 主应用启动类 -│ ├── listener/ # 应用监听器 -│ │ └── ApplicationStartupListener.java -│ ├── monitor/ # 监控相关 -│ └── web/ # Web层 -│ ├── controller/ # 控制器层 -│ │ ├── IotControllerV1.java # IoT设备通信控制器 -│ │ ├── InnerController.java # 内部系统调用接口 -│ │ ├── LocationController.java # 位置和地理围栏控制器 -│ │ ├── TestController.java # 测试接口控制器 -│ │ ├── VersionController.java # 版本信息控制器 -│ │ ├── TCLController.java # TCL设备控制器 -│ │ └── OAuth2TokenController.java # OAuth2令牌控制器 -│ ├── config/ # 配置类 -│ │ ├── DefaultSecurityConfig.java # 安全配置 -│ │ ├── RedisConfig.java # Redis配置 -│ │ ├── SwaggerConfig.java # API文档配置 -│ │ ├── JacksonConfig.java # JSON序列化配置 -│ │ ├── AsyncExecuteConfig.java # 异步执行配置 -│ │ ├── VirtualThreadConfig.java # 虚拟线程配置 -│ │ └── ... # 其他配置类 -│ ├── context/ # 上下文 -│ ├── oauth/ # OAuth2相关 -│ ├── auth/ # 认证相关 -│ └── utils/ # 工具类 -├── src/main/resources/ # 配置文件 -│ ├── application-dev.properties # 开发环境配置 -│ ├── application-prod.properties # 生产环境配置 -│ └── ... -└── src/bin/ # 部署脚本 - ├── Dockerfile # Docker镜像配置 - ├── restart.sh # 重启脚本 - └── ... -``` - -## 核心功能 - -### 1. IoT设备通信 (IotControllerV1) - -提供IoT设备与平台之间的通信接口: - -- **设备上行数据接收**:支持HTTP、TCP等多种协议 -- **设备下行指令发送**:支持加密和未加密两种模式 -- **第三方平台集成**:乐橙、移动OneNet等平台对接 -- **设备影子查询**:获取设备状态信息 -- **产品信息查询**:获取产品配置信息 - -**主要接口:** - -- `POST /iot/v1/down/{productKey}` - 设备下行指令(加密) -- `POST /iot/http/up/{productKey}/{deviceId}` - HTTP上行数据 -- `GET /iot/device/shadow/{iotId}` - 查询设备影子 -- `GET /iot/product/{productKey}` - 查询产品信息 - -### 2. 内部系统调用 (InnerController) - -提供系统内部服务间的调用接口: - -- **用户管理**:新增、删除用户 -- **应用管理**:创建用户应用和OAuth客户端 -- **许可证管理**:查询和充值设备接入额度 -- **设备日志查询**:获取设备事件元数据 - -**主要接口:** - -- `POST /inner/user` - 新增用户 -- `DELETE /inner/user` - 删除用户 -- `POST /inner/application` - 新增用户应用 -- `GET /inner/license` - 查询许可证信息 - -### 3. 位置和地理围栏 (LocationController) - -提供设备位置服务和地理围栏功能: - -- **地理围栏管理**:创建、修改、删除围栏 -- **围栏与设备关联**:管理设备与围栏的绑定关系 -- **围栏触发规则**:配置围栏触发条件和时间规则 - -**主要接口:** - -- `POST /iot/location/selectFence` - 查询围栏列表 -- `POST /iot/location/setFence` - 创建地理围栏 -- `POST /iot/location/updateFence` - 修改地理围栏 -- `DELETE /iot/location/{id}` - 删除地理围栏 - -### 4. 安全配置 (DefaultSecurityConfig) - -提供全面的安全保护机制: - -- **环境自适应**:开发和生产环境不同的安全策略 -- **JWT认证**:基于JWT的API认证 -- **IP白名单**:支持IP地址访问控制 -- **CORS配置**:跨域资源共享配置 -- **端点保护**:Actuator等敏感端点的访问控制 - -## 技术特性 - -### 1. 多级缓存支持 - -- 集成Redis分布式缓存 -- 支持本地缓存和分布式缓存 -- 提供缓存统计和监控 - -### 2. 异步处理 - -- 支持虚拟线程(JDK 21) -- 异步任务执行配置 -- 线程池监控和管理 - -### 3. 监控和可观测性 - -- Spring Boot Actuator集成 -- 自定义健康检查 -- 应用启动监控 -- 性能指标收集 - -### 4. API文档 - -- Knife4j集成 -- OpenAPI 3.0规范 -- 自动生成API文档 - -## 配置说明 - -### 环境配置 - -**开发环境 (application-dev.properties):** - -```properties -# 服务器配置 -server.port=8080 -server.servlet.context-path=/api -# 安全配置 -security.production.enabled=false -security.actuator.enabled=true -# 数据库配置 -spring.datasource.url=jdbc:mysql://localhost:3306/iot_universal -spring.datasource.username=root -spring.datasource.password=password -# Redis配置 -spring.redis.host=localhost -spring.redis.port=6379 -``` - -**生产环境 (application-prod.properties):** - -```properties -# 安全配置 -security.production.enabled=true -security.allowed.ips=192.168.1.100,192.168.1.101 -security.actuator.enabled=false -# 性能优化 -spring.jvm.memory=-Xms2g -Xmx4g -spring.threads.virtual.enabled=true -``` - -### 安全配置 - -**IP白名单配置:** - -```properties -# 允许访问的IP地址(逗号分隔) -security.allowed.ips=192.168.1.100,192.168.1.101,10.0.0.50 -# 允许访问的主机名 -security.allowed.hosts=example.com,api.example.com -``` - -**OAuth2配置:** - -```properties -# OAuth2服务器配置 -spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080 -spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8080/.well-known/jwks.json -``` - -## 部署指南 - -### 1. 本地开发 - -```bash -# 克隆项目 -git clone -cd cn-universal-web - -# 编译项目 -mvn clean compile - -# 运行应用 -mvn spring-boot:run -``` - -### 2. Docker部署 - -```bash -# 构建镜像 -docker build -t platform-universal-web:latest . - -# 运行容器 -docker run -d \ - --name platform-universal-web \ - -p 8080:8080 \ - -e SPRING_PROFILES_ACTIVE=prod \ - platform-universal-web:latest -``` - -### 3. 生产部署 - -```bash -# 使用部署脚本 -./src/bin/restart.sh - -# 或手动部署 -mvn clean package -Dmaven.test.skip=true -java -jar target/cn-universal-web-1.4-SNAPSHOT.jar --spring.profiles.active=prod -``` - -## 监控和维护 - -### 1. 健康检查 - -```bash -# 应用健康状态 -curl http://localhost:8080/actuator/health - -# 详细健康信息 -curl http://localhost:8080/actuator/health/details -``` - -### 2. 性能监控 - -```bash -# 应用指标 -curl http://localhost:8080/actuator/metrics - -# JVM指标 -curl http://localhost:8080/actuator/metrics/jvm.memory.used -``` - -### 3. 日志管理 - -```bash -# 查看应用日志 -tail -f logs/platform-universal-web.log - -# 查看错误日志 -grep ERROR logs/platform-universal-web.log -``` - -## 扩展开发 - -### 1. 添加新的控制器 - -```java -@RestController -@RequestMapping("/api/v1/custom") -@Slf4j -public class CustomController extends BaseController { - - @PostMapping("/operation") - public R customOperation(@RequestBody CustomRequest request) { - // 实现业务逻辑 - return R.ok(result); - } -} -``` - -### 2. 添加新的配置 - -```java -@Configuration -@EnableConfigurationProperties(CustomProperties.class) -public class CustomConfig { - - @Bean - public CustomService customService() { - return new CustomService(); - } -} -``` - -### 3. 添加新的监听器 - -```java -@Component -public class CustomEventListener implements ApplicationListener { - - @Override - public void onApplicationEvent(CustomEvent event) { - // 处理自定义事件 - } -} -``` - -## 故障排除 - -### 1. 常见问题 - -**应用启动失败:** - -- 检查数据库连接配置 -- 验证Redis服务状态 -- 查看端口占用情况 - -**API访问被拒绝:** - -- 检查安全配置 -- 验证IP白名单设置 -- 确认JWT令牌有效性 - -**性能问题:** - -- 检查JVM内存配置 -- 监控线程池状态 -- 分析缓存命中率 - -### 2. 调试模式 - -```bash -# 启用调试日志 -java -jar app.jar --debug - -# 启用详细日志 -java -jar app.jar --logging.level.cn.universal=DEBUG -``` - -## 版本历史 - -- **v1.4-SNAPSHOT** - 当前版本 - - 支持JDK 21和虚拟线程 - - 增强安全配置 - - 优化缓存机制 - - 完善监控功能 - -- **v1.3** - 历史版本 - - 基础IoT功能 - - OAuth2认证 - - 地理围栏支持 - -## 贡献指南 - -1. Fork项目 -2. 创建功能分支 -3. 提交更改 -4. 推送到分支 -5. 创建Pull Request - -## 许可证 - -Copyright (c) 2025, IoT-Universal. All Rights Reserved. - ---- - -**作者:** Aleo -**邮箱:** wo8335224@gmail.com -**微信:** outlookFil \ No newline at end of file