clientIdentifiers) {
+ log.info("MQTT Broker 关闭连接 {}", clientIdentifiers.toString());
+ JSONObject param = new JSONObject();
+ param.put("ids", clientIdentifiers);
+ String result = HttpRequest.post("http://127.0.0.1:60000/smqtt/close/connection")
+ .header("Content-Type", "application/json;charset=UTF-8")
+ .body(param.toString())
+ .execute().body();
+ return R.ok(result);
+ }
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/MqttBrokerService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/MqttBrokerService.java
new file mode 100644
index 00000000..1f15eae9
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/MqttBrokerService.java
@@ -0,0 +1,36 @@
+package com.mqttsnet.thinglinks.broker.service;
+
+import com.mqttsnet.thinglinks.broker.api.domain.model.PublishMessageRequest;
+import com.mqttsnet.thinglinks.common.core.exception.base.BaseException;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: MqttBrokerService.java
+ * -----------------------------------------------------------------------------
+ * Description:
+ * MqttBroker API
+ * -----------------------------------------------------------------------------
+ *
+ * @author ShiHuan Sun
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ *
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023-10-31 19:43
+ */
+public interface MqttBrokerService {
+
+
+ /**
+ * Publishes a message to a specified topic and returns the content if successful.
+ *
+ * @param publishMessageRequest Object containing the required parameters for publishing.
+ * @return The content of the published message.
+ * @throws BaseException If the publishing fails.
+ */
+ String publishMessage(PublishMessageRequest publishMessageRequest);
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/impl/MqttBrokerServiceImpl.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/impl/MqttBrokerServiceImpl.java
new file mode 100644
index 00000000..391b6442
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/impl/MqttBrokerServiceImpl.java
@@ -0,0 +1,88 @@
+package com.mqttsnet.thinglinks.broker.service.impl;
+
+import com.mqttsnet.thinglinks.broker.api.BifroMQApi;
+import com.mqttsnet.thinglinks.broker.api.domain.model.PublishMessageRequest;
+import com.mqttsnet.thinglinks.broker.service.MqttBrokerService;
+import com.mqttsnet.thinglinks.common.core.exception.base.BaseException;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: MqttBrokerServiceImpl.java
+ * -----------------------------------------------------------------------------
+ * Description:
+ * MqttBroker API 实现类
+ * -----------------------------------------------------------------------------
+ *
+ * @author ShiHuan Sun
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ *
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023-10-31 19:44
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class MqttBrokerServiceImpl implements MqttBrokerService {
+ private final BifroMQApi bifroMQApi;
+
+
+ /**
+ * Publishes a message to a specified topic and returns the content if successful.
+ *
+ * @param publishMessageRequest Object containing the required parameters for publishing.
+ * @return The content of the published message.
+ * @throws BaseException If the publishing fails.
+ */
+ @Override
+ public String publishMessage(PublishMessageRequest publishMessageRequest) throws BaseException {
+ log.info("Preparing to publish message with topic: {}", publishMessageRequest.getTopic());
+ try {
+ ResponseEntity response = callPublishApi(publishMessageRequest);
+
+ if (response.getStatusCode().is2xxSuccessful()) {
+ log.info("Successfully published message with topic: {}", publishMessageRequest.getTopic());
+ return publishMessageRequest.getPayload(); // Return the message content that was published
+ } else {
+ log.error("Failed to publish message with topic: {}. Response Status: {}",
+ publishMessageRequest.getTopic(), response.getStatusCode());
+ throw new BaseException("Failed to publish message with topic: " + publishMessageRequest.getTopic());
+ }
+ } catch (HttpClientErrorException e) {
+ log.error("HTTP error occurred while publishing message: {}", e.getMessage());
+ throw new BaseException("Error during message publishing: " + e.getResponseBodyAsString());
+ } catch (Exception e) {
+ log.error("Unexpected error occurred while publishing message: {}", e.getMessage());
+ throw new BaseException("Unexpected error during message publishing: " + e.getMessage());
+ }
+ }
+
+
+ /**
+ * Makes the actual API call to publish a message.
+ *
+ * @param publishMessageRequest Object containing the required parameters for publishing.
+ * @return R Response indicating success or failure from the BifroMQApi.
+ */
+ private ResponseEntity callPublishApi(PublishMessageRequest publishMessageRequest) {
+ return bifroMQApi.publishMessage(
+ publishMessageRequest.getReqId(),
+ publishMessageRequest.getTenantId(),
+ publishMessageRequest.getTopic(),
+ publishMessageRequest.getClientType(),
+ publishMessageRequest.getPubQos(),
+ publishMessageRequest.getRetain(),
+ publishMessageRequest.getClientMeta(),
+ publishMessageRequest.getPayload()
+ );
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/pom.xml b/thinglinks-modules/thinglinks-modules-link/pom.xml
index d98de5f8..71f7f6bd 100644
--- a/thinglinks-modules/thinglinks-modules-link/pom.xml
+++ b/thinglinks-modules/thinglinks-modules-link/pom.xml
@@ -80,24 +80,17 @@
${thinglinks.version}
-
+
com.mqttsnet
- thinglinks-api-link
+ thinglinks-common-kafka
${thinglinks.version}
-
-
-
-
+
com.mqttsnet
- thinglinks-common-kafka
+ thinglinks-api-link
${thinglinks.version}
diff --git a/thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/config/KafkaConsumerConfig.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaConsumerConfig.java
similarity index 97%
rename from thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/config/KafkaConsumerConfig.java
rename to thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaConsumerConfig.java
index 75f80a52..d4df6df5 100644
--- a/thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/config/KafkaConsumerConfig.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaConsumerConfig.java
@@ -1,4 +1,4 @@
-package com.mqttsnet.thinglinks.common.kafka.config;
+package com.mqttsnet.thinglinks.link.common.config;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
@@ -17,9 +17,9 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: KafkaConsumerConfig
- * @packagename: com.mqttsnet.thinglinks.config.kafka
+ * @packagename: com.mqttsnet.thinglinks.common.kafka.config
* @author: ShiHuan Sun
* @e-mainl: 13733918655@163.com
* @date: 2023-06-18 11:29
diff --git a/thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/config/KafkaProviderConfig.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaProviderConfig.java
similarity index 85%
rename from thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/config/KafkaProviderConfig.java
rename to thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaProviderConfig.java
index f07be428..92fe8016 100644
--- a/thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/config/KafkaProviderConfig.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaProviderConfig.java
@@ -1,4 +1,4 @@
-package com.mqttsnet.thinglinks.common.kafka.config;
+package com.mqttsnet.thinglinks.link.common.config;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.springframework.beans.factory.annotation.Value;
@@ -14,9 +14,9 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: KafkaProviderConfig
- * @packagename: com.mqttsnet.thinglinks.config.kafka
+ * @packagename: com.mqttsnet.thinglinks.common.kafka.config
* @author: ShiHuan Sun
* @e-mainl: 13733918655@163.com
* @date: 2023-06-18 11:28
@@ -24,17 +24,18 @@
@Configuration
public class KafkaProviderConfig {
- @Value("${spring.kafka.thingLinksPro.producer.bootstrap-servers}")
+
+ @Value("${spring.kafka.thingLinks.producer.bootstrap-servers}")
private String bootstrapServers;
- @Value("${spring.kafka.thingLinksPro.producer.transaction-id-prefix}")
+ @Value("${spring.kafka.thingLinks.producer.transaction-id-prefix}")
private String transactionIdPrefix;
- @Value("${spring.kafka.thingLinksPro.producer.acks}")
+ @Value("${spring.kafka.thingLinks.producer.acks}")
private String acks;
- @Value("${spring.kafka.thingLinksPro.producer.retries}")
+ @Value("${spring.kafka.thingLinks.producer.retries}")
private String retries;
- @Value("${spring.kafka.thingLinksPro.producer.batch-size}")
+ @Value("${spring.kafka.thingLinks.producer.batch-size}")
private String batchSize;
- @Value("${spring.kafka.thingLinksPro.producer.buffer-memory}")
+ @Value("${spring.kafka.thingLinks.producer.buffer-memory}")
private String bufferMemory;
@Bean
@@ -82,7 +83,7 @@ public KafkaTransactionManager kafkaTransactionManager(ProducerF
}
@Bean
- public KafkaTemplate thingLinksProKafkaTemplate() {
+ public KafkaTemplate thingLinksKafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
index e88b5ac6..6e573661 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
@@ -3,23 +3,15 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mqttsnet.thinglinks.common.core.enums.MqttEvent;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerGroupConstant;
import com.mqttsnet.thinglinks.common.kafka.constant.ConsumerTopicConstant;
import com.mqttsnet.thinglinks.link.service.device.DeviceActionService;
import com.mqttsnet.thinglinks.link.service.device.DeviceDatasService;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.apache.rocketmq.spring.annotation.MessageModel;
-import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
-import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Component;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.Map;
import java.util.Objects;
/**
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
index a1d1f515..7c2afd17 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
@@ -39,8 +39,8 @@ public class DeviceActionMessageRocketmqConsumer implements RocketMQListener {
@Async("linkAsync")
@Override
public void onMessage(Object message) {
- if (null == message){
- log.warn("message cannot be empty {}",message);
+ if (null == message) {
+ log.warn("message cannot be empty {}", message);
return;
}
log.info("ThingLinks物联网平台数据消费-->Received message={}", message);
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/kafka/KafkaController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/kafka/KafkaController.java
index 6bc76417..3715d1d6 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/kafka/KafkaController.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/kafka/KafkaController.java
@@ -1,6 +1,5 @@
package com.mqttsnet.thinglinks.link.controller.kafka;
-import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
@@ -32,8 +31,8 @@ public class KafkaController {
@Transactional
@PostMapping("/send")
- public String kafkaMessageSend(@RequestBody Map params){
- thingLinksProKafkaTemplate.send(new ProducerRecord<>(String.valueOf(params.get("topic")),String.valueOf(params.get("msg"))));
- return "success-"+params.get("topic");
+ public String kafkaMessageSend(@RequestBody Map params) {
+ thingLinksProKafkaTemplate.send(new ProducerRecord<>(String.valueOf(params.get("topic")), String.valueOf(params.get("msg"))));
+ return "success-" + params.get("topic");
}
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceDatasServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceDatasServiceImpl.java
index 64203356..24ef248a 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceDatasServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceDatasServiceImpl.java
@@ -190,7 +190,7 @@ public void insertBaseDatas(JSONObject thinglinksMessage) throws Exception {
param.put("qos", Integer.valueOf(qos));
param.put("retain", false);
param.put("message", payload);
- remoteMqttBrokerOpenApi.sendMessage(param);
+// remoteMqttBrokerOpenApi.sendMessage(param);
} else if (topic.startsWith("/v1/devices/") && topic.endsWith("/topo/delete")) {
final String deviceIdentification = SubStringUtil.subStr(topic, 12, -12);
final String payload = this.processingTopoDeleteTopic(deviceIdentification, body);
@@ -199,7 +199,7 @@ public void insertBaseDatas(JSONObject thinglinksMessage) throws Exception {
param.put("qos", Integer.valueOf(qos));
param.put("retain", false);
param.put("message", payload);
- remoteMqttBrokerOpenApi.sendMessage(param);
+// remoteMqttBrokerOpenApi.sendMessage(param);
} else if (topic.startsWith("/v1/devices/") && topic.endsWith("/topo/update")) {
final String deviceIdentification = SubStringUtil.subStr(topic, 12, -12);
final String payload = this.processingTopoUpdateTopic(deviceIdentification, body);
@@ -208,7 +208,7 @@ public void insertBaseDatas(JSONObject thinglinksMessage) throws Exception {
param.put("qos", Integer.valueOf(qos));
param.put("retain", false);
param.put("message", payload);
- remoteMqttBrokerOpenApi.sendMessage(param);
+// remoteMqttBrokerOpenApi.sendMessage(param);
} else if (topic.startsWith("/v1/devices/") && topic.endsWith("/datas")) {
final String deviceIdentification = SubStringUtil.subStr(topic, 12, -6);
this.processingDatasTopic(deviceIdentification, body);
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceInfoServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceInfoServiceImpl.java
index 32638eaf..8e55a4a5 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceInfoServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceInfoServiceImpl.java
@@ -239,7 +239,7 @@ public int deleteDeviceInfoByIds(Long[] ids) {
param.put("qos", 2);
param.put("retain", false);
param.put("message", JSON.toJSONString(responseMaps));
- remoteMqttBrokerOpenApi.sendMessage(param);
+// remoteMqttBrokerOpenApi.sendMessage(param);
}
responseMaps.clear();
});
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
index 9b63714e..a22b21fa 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
@@ -9,7 +9,6 @@
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.enums.DataTypeEnum;
import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
-import com.mqttsnet.thinglinks.common.core.mqs.SelectorConfig;
import com.mqttsnet.thinglinks.common.core.text.CharsetKit;
import com.mqttsnet.thinglinks.common.core.text.UUID;
import com.mqttsnet.thinglinks.common.core.utils.StringUtils;
@@ -35,12 +34,10 @@
import com.mqttsnet.thinglinks.tdengine.api.domain.Fields;
import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDto;
import lombok.extern.slf4j.Slf4j;
-import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
-import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
@@ -54,7 +51,6 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
-import java.util.stream.Collectors;
/**
* @Description: 产品模型业务层
@@ -88,12 +84,6 @@ public class ProductServiceImpl implements ProductService {
@Autowired
private RocketMQTemplate rocketMQTemplate;
- @Autowired
- private KafkaTemplate thingLinksProKafkaTemplate;
-
- @Autowired
- private SelectorConfig selectorConfig;
-
/**
* 数据库名称
*/
@@ -675,11 +665,7 @@ public List createSuperTableDataModel(Long[] productIds, Boolean
jsonObject.put("msg", JSON.toJSONString(superTableDto));
mqMessage.setMessage(jsonObject.toJSONString());
- if (selectorConfig.isSelectorKafka()) {
- thingLinksProKafkaTemplate.send(new ProducerRecord<>(mqMessage.getTopic(), mqMessage.getMessage()));
- } else {
- rocketMQTemplate.convertAndSend(mqMessage.getTopic(), mqMessage.getMessage());
- }
+ rocketMQTemplate.convertAndSend(mqMessage.getTopic(), mqMessage.getMessage());
}
}
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/resources/bootstrap.yml b/thinglinks-modules/thinglinks-modules-link/src/main/resources/bootstrap.yml
index 6be2c6c2..dd7fcb63 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/resources/bootstrap.yml
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/resources/bootstrap.yml
@@ -35,5 +35,7 @@ spring:
refresh: true
- dataId: rocketmq.yml
refresh: false
+ - dataId: kafka.yml
+ refresh: false
username: @nacos.username@
password: @nacos.password@
diff --git a/thinglinks-modules/thinglinks-modules-rule/pom.xml b/thinglinks-modules/thinglinks-modules-rule/pom.xml
index 607de6dd..87083355 100644
--- a/thinglinks-modules/thinglinks-modules-rule/pom.xml
+++ b/thinglinks-modules/thinglinks-modules-rule/pom.xml
@@ -101,13 +101,6 @@
${thinglinks.version}
-
-
- com.mqttsnet
- thinglinks-common-kafka
- ${thinglinks.version}
-
-
com.mqttsnet
diff --git a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/ThingLinksBeanDefinitionRegistrar.java b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/ThingLinksBeanDefinitionRegistrar.java
deleted file mode 100644
index c3f0cfbf..00000000
--- a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/ThingLinksBeanDefinitionRegistrar.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.mqttsnet.thinglinks.rule;
-
-import com.mqttsnet.thinglinks.common.core.mqs.SelectorConfig;
-import com.mqttsnet.thinglinks.rule.common.consumer.kafka.RuleTriggerMessageKafkaConsumer;
-import com.mqttsnet.thinglinks.rule.common.consumer.rocketmq.RuleTriggerMessageRocketmqConsumer;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
-import org.springframework.core.env.Environment;
-import org.springframework.core.type.AnnotationMetadata;
-
-@Configuration
-class ThingLinksConfiguration {
-
- @Bean
- public ThingLinksBeanDefinitionRegistrar thingLinksBeanDefinitionRegistrar(Environment environment) {
- return new ThingLinksBeanDefinitionRegistrar(environment);
- }
-}
-
-public class ThingLinksBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
-
- private final Environment environment;
-
- public ThingLinksBeanDefinitionRegistrar(Environment environment) {
- this.environment = environment;
- }
-
- @Override
- public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
- Class> beanClass = getConsumerClass();
- String beanName = beanClass.getSimpleName();
- registerBeanDefinition(registry, beanClass, beanName);
- }
-
- private Class> getConsumerClass() {
- boolean selectorKafka = Boolean.parseBoolean(environment.getProperty(SelectorConfig.selectorKafkaKey, "false"));
- return selectorKafka ? RuleTriggerMessageKafkaConsumer.class :
- RuleTriggerMessageRocketmqConsumer.class;
- }
-
- private void registerBeanDefinition(BeanDefinitionRegistry registry, Class> beanClass, String beanName) {
- AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(beanClass).getBeanDefinition();
- registry.registerBeanDefinition(beanName, beanDefinition);
- }
-}
diff --git a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/ThingLinksRuleApplication.java b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/ThingLinksRuleApplication.java
index 467e200a..c25b53e2 100644
--- a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/ThingLinksRuleApplication.java
+++ b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/ThingLinksRuleApplication.java
@@ -5,7 +5,6 @@
import com.mqttsnet.thinglinks.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.CrossOrigin;
/**
@@ -22,7 +21,6 @@
//若maxAge是负数,则代表为临时Cookie,不会被持久化,Cookie信息保存在浏览器内存中,浏览器关闭Cookie就消失
@CrossOrigin(origins = "*", maxAge = 3600)
@SpringBootApplication(scanBasePackages = {"com.mqttsnet.thinglinks"})
-@Import(ThingLinksBeanDefinitionRegistrar.class)
public class ThingLinksRuleApplication {
public static void main(String[] args) {
SpringApplication.run(ThingLinksRuleApplication.class, args);
diff --git a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/common/consumer/kafka/RuleTriggerMessageKafkaConsumer.java b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/common/consumer/kafka/RuleTriggerMessageKafkaConsumer.java
deleted file mode 100644
index 4df94ef2..00000000
--- a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/common/consumer/kafka/RuleTriggerMessageKafkaConsumer.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.mqttsnet.thinglinks.rule.common.consumer.kafka;
-
-import com.alibaba.fastjson.JSONObject;
-import com.mqttsnet.thinglinks.common.kafka.constant.ConsumerTopicConstant;
-import com.mqttsnet.thinglinks.rule.service.RuleDeviceLinkageService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.kafka.annotation.KafkaListener;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Component;
-
-/**
- * @Description: 规则引擎-触发器规则消息消费(kafka模式)
- * @Author: ShiHuan Sun
- * @E-mail: 13733918655@163.com
- * @Website: http://thinglinks.mqttsnet.com
- * @CreateDate: 2022/10/28$ 16:11$
- * @UpdateUser: ShiHuan Sun
- * @UpdateDate: 2022/10/28$ 16:11$
- * @UpdateRemark: 修改内容
- * @Version: 1.0
- */
-@Slf4j
-//@Component
-public class RuleTriggerMessageKafkaConsumer {
-
- @Autowired
- private RuleDeviceLinkageService ruleDeviceLinkageService;
-
- @Async("ruleAsync")
- @KafkaListener(topics = {ConsumerTopicConstant.THINGLINKS_RULE_TRIGGER})
- public void onMessage(ConsumerRecord, ?> record) {
- if (null == record) {
- log.warn("message cannot be empty {}", record);
- return;
- }
-
- log.info("规则引擎-触发器规则数据消费-->Received message={}", record);
-
- try {
-
- Object message = JSONObject.parse(String.valueOf(record.value()));
- JSONObject json = JSONObject.parseObject(message.toString());
- Boolean flag = ruleDeviceLinkageService.checkRuleConditions(json.getString("msg"));
- log.info("规则匹配结果:{}", flag);
- //触发执行动作
- if(flag) {
- ruleDeviceLinkageService.execAction(json.getString("msg"));
- }
-
- } catch (Exception e) {
- log.error("规则引擎-触发器规则数据消费-->消费失败,失败原因:{}", e.getMessage());
- }
- }
-}
diff --git a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/service/impl/RuleDeviceLinkageServiceImpl.java b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/service/impl/RuleDeviceLinkageServiceImpl.java
index bda53800..78cf36e0 100644
--- a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/service/impl/RuleDeviceLinkageServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/service/impl/RuleDeviceLinkageServiceImpl.java
@@ -1,20 +1,16 @@
package com.mqttsnet.thinglinks.rule.service.impl;
import com.alibaba.fastjson.JSONObject;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.enums.ConditionTypeEnum;
import com.mqttsnet.thinglinks.common.core.enums.FieldTypeEnum;
import com.mqttsnet.thinglinks.common.core.enums.OperatorEnum;
import com.mqttsnet.thinglinks.common.core.enums.TriggeringEnum;
-import com.mqttsnet.thinglinks.common.core.mqs.SelectorConfig;
import com.mqttsnet.thinglinks.common.core.utils.CompareUtil;
import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerTopicConstant;
import com.mqttsnet.thinglinks.common.rocketmq.domain.MQMessage;
import com.mqttsnet.thinglinks.link.api.*;
-import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.ProductProperties;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.ProductServices;
@@ -29,10 +25,8 @@
import com.mqttsnet.thinglinks.tdengine.api.domain.TagsSelectDao;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
-import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.HtmlUtils;
@@ -52,15 +46,10 @@
@Service
public class RuleDeviceLinkageServiceImpl implements RuleDeviceLinkageService {
- @Autowired
- private KafkaTemplate thingLinksProKafkaTemplate;
@Autowired
private RocketMQTemplate rocketMQTemplate;
- @Autowired
- private SelectorConfig selectorConfig;
-
@Autowired
private ActionCommandsService actionCommandsService;
@@ -109,11 +98,7 @@ public void triggerDeviceLinkageByRuleIdentification(String ruleIdentification)
log.info("topic:{}", mqMessage.getTopic());
log.info("message:{}", mqMessage.getMessage());
- if (selectorConfig.isSelectorKafka()) {
- thingLinksProKafkaTemplate.send(new ProducerRecord<>(mqMessage.getTopic(), mqMessage.getMessage()));
- } else {
- rocketMQTemplate.convertAndSend(mqMessage.getTopic(), mqMessage.getMessage());
- }
+ rocketMQTemplate.convertAndSend(mqMessage.getTopic(), mqMessage.getMessage());
}
/**
diff --git a/thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/common/consumer/kafka/ProductCreateSuperTableMessageKafkaConsumer.java b/thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/common/consumer/kafka/ProductCreateSuperTableMessageKafkaConsumer.java
deleted file mode 100644
index 0c202c2d..00000000
--- a/thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/common/consumer/kafka/ProductCreateSuperTableMessageKafkaConsumer.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.mqttsnet.thinglinks.tdengine.common.consumer.kafka;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONException;
-import com.alibaba.fastjson.JSONObject;
-import com.mqttsnet.thinglinks.common.core.utils.StringUtils;
-import com.mqttsnet.thinglinks.common.kafka.constant.ConsumerTopicConstant;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerGroupConstant;
-import com.mqttsnet.thinglinks.tdengine.service.ProductSuperTableCreateOrUpdateService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.apache.rocketmq.spring.annotation.MessageModel;
-import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
-import org.apache.rocketmq.spring.core.RocketMQListener;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.kafka.annotation.KafkaListener;
-import org.springframework.stereotype.Component;
-
-/**
- * @Description: TDengine超级表创键修改动作监听(kafka模式)
- * @Author: ShiHuan Sun
- * @E-mail: 13733918655@163.com
- * @Website: http://thinglinks.mqttsnet.com
- * @CreateDate: 2021/11/22$ 16:11$
- * @UpdateUser: ShiHuan Sun
- * @UpdateDate: 2021/11/22$ 16:11$
- * @UpdateRemark: 修改内容
- * @Version: 1.0
- */
-@Slf4j
-//@Component
-public class ProductCreateSuperTableMessageKafkaConsumer {
-
- @Autowired
- private ProductSuperTableCreateOrUpdateService productSuperTableCreateOrUpdateService;
-
- /**
- * 超级表创建及修改处理
- *
- * @param record
- */
- @KafkaListener(topics = {ConsumerTopicConstant.PRODUCTSUPERTABLE_CREATEORUPDATE})
- public void onMessage(ConsumerRecord, ?> record) {
-
- try {
- // 消息处理逻辑
- if (null == record) {
- log.warn("message cannot be empty {}", record);
- return;
- }
-
- Object message = JSONObject.parse(String.valueOf(record.value()));
- JSONObject stableMessage = JSONObject.parseObject(message.toString());
- log.info("TDengine消费{}超级表消息:{}", stableMessage.get("type"), stableMessage.get("msg"));
- if ("create".equals(stableMessage.get("type"))) {
- try {
- productSuperTableCreateOrUpdateService.createProductSuperTable(String.valueOf(stableMessage.get("msg")));
- } catch (Exception e) {
- log.error(e.getMessage());
- }
- } else if ("update".equals(stableMessage.get("type"))) {
- productSuperTableCreateOrUpdateService.updateProductSuperTable(String.valueOf(stableMessage.get("msg")));
- }
- } catch (Exception e) {
- // 记录具体错误信息和相关内容
- log.error(e.getMessage());
- }
-
- }
-}
From e7e1a45851a0832bf1bb0abdee4635778fcf2d2b Mon Sep 17 00:00:00 2001
From: xiaonan <13733918655@163.com>
Date: Mon, 4 Mar 2024 16:55:36 +0800
Subject: [PATCH 07/35] =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=8D=8F=E8=AE=AE?=
=?UTF-8?q?=E5=8D=87=E7=BA=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
doc/sql/changeRecord/1.2.0.RELEASE.sql | 17 +-
doc/sql/thinglinks.sql | 63 ++--
.../broker/api/RemoteMqttBrokerOpenApi.java | 6 +-
.../PublishMessageRequestVO.java} | 4 +-
.../RemoteMqttBrokerOpenApiFallback.java | 6 +-
.../link/api/RemoteDeviceService.java | 143 +++++++-
.../domain/cache/device/DeviceCacheVO.java | 41 +++
.../domain/cache/product/ProductCacheVO.java | 35 ++
.../cache/product/ProductModelCacheVO.java | 29 ++
.../link/api/domain/device/entity/Device.java | 54 ++-
.../domain/device/entity/DeviceAction.java | 9 +-
.../api/domain/device/entity/DeviceDatas.java | 8 +-
.../domain/device/entity/DeviceLocation.java | 10 +-
.../api/domain/device/entity/DeviceTopic.java | 8 +-
.../enumeration/DeviceActionTypeEnum.java | 54 +++
.../domain/deviceInfo/entity/DeviceInfo.java | 10 +-
.../api/domain/product/entity/Product.java | 10 +-
.../product/entity/ProductCommands.java | 9 +-
.../entity/ProductCommandsRequests.java | 8 +-
.../entity/ProductCommandsResponse.java | 8 +-
.../product/entity/ProductProperties.java | 9 +-
.../product/entity/ProductServices.java | 11 +-
.../product/entity/ProductTemplate.java | 11 +-
.../link/api/domain/protocol/Protocol.java | 10 +-
.../vo/param/CommandIssueRequestParam.java | 64 ++++
.../vo/param/DeviceCommandWrapperParam.java | 44 +++
.../vo/param/OpenAiChatRequestParam.java | 60 ++++
.../vo/param/OtaCommandRequestParam.java | 62 ++++
.../vo/param/OtaCommandResponseParam.java | 71 ++++
.../vo/param/TopoAddSubDeviceParam.java | 65 ++++
.../vo/param/TopoDeleteSubDeviceParam.java | 42 +++
.../vo/param/TopoDeviceDataReportParam.java | 78 +++++
.../domain/vo/param/TopoQueryDeviceParam.java | 37 ++
.../param/TopoUpdateSubDeviceStatusParam.java | 63 ++++
.../vo/result/DeviceCommandResultVO.java | 75 ++++
.../vo/result/OpenAiChatResponseResultVO.java | 128 +++++++
.../result/ProtocolDataMessageResultVO.java | 53 +++
.../vo/result/TopoAddDeviceResultVO.java | 79 +++++
.../result/TopoDeviceOperationResultVO.java | 58 ++++
.../vo/result/TopoQueryDeviceResultVO.java | 136 ++++++++
.../factory/RemoteDeviceFallbackFactory.java | 143 +++++++-
.../api/domain/SuperTableDescribeVO.java | 56 +++
thinglinks-common/pom.xml | 1 +
.../thinglinks-common-core/pom.xml | 2 +-
.../common/core/constant/CacheConstants.java | 35 +-
.../common/core/constant/Constants.java | 15 -
.../core/enums/DeviceConnectStatus.java | 36 --
.../core/enums/DeviceConnectStatusEnum.java | 69 ++++
.../core/mqs/ConsumerGroupConstant.java | 19 +
.../core/mqs/ConsumerTopicConstant.java | 102 ++++++
.../common/core/utils/AesUtils.java | 145 ++++++++
.../common/core/utils/SHA256Utils.java | 67 ++++
.../common/core/utils/Sm4Utils.java | 101 ++++++
.../common/core/utils/SnowflakeIdUtil.java | 143 ++++++++
.../common/core/utils/bean/BeanPlusUtil.java | 40 +++
.../kafka/constant/ConsumerTopicConstant.java | 82 -----
.../thinglinks-common-protocol/README.md | 4 +
.../thinglinks-common-protocol/pom.xml | 24 ++
.../factory/ProtocolMessageAdapter.java | 76 ++++
.../protocol/model/EncryptionDetailsDTO.java | 69 ++++
.../model/ProtocolDataMessageDTO.java | 68 ++++
...ProtocolMessageSignatureVerifierUtils.java | 285 +++++++++++++++
...tocolRegexTopicVariableExtractorUtils.java | 47 +++
...ot.autoconfigure.AutoConfiguration.imports | 1 +
.../constant/ConsumerGroupConstant.java | 42 ---
.../constant/ConsumerTopicConstant.java | 39 ---
.../thinglinks-modules-broker/pom.xml | 21 ++
.../common/asyncthread/BrokerAsyncConfig.java | 94 +++++
.../broker/config/KafkaConsumerConfig.java | 109 ++++++
.../broker/config/KafkaProviderConfig.java | 90 +++++
.../controller/MqttBrokerOpenController.java | 10 +-
.../broker/mqs/event/MqttCloseEvent.java | 31 ++
.../broker/mqs/event/MqttConnectEvent.java | 31 ++
.../broker/mqs/event/MqttDisconnectEvent.java | 31 ++
.../broker/mqs/event/MqttPingEvent.java | 31 ++
.../broker/mqs/event/MqttPublishEvent.java | 32 ++
.../broker/mqs/event/MqttSubscribeEvent.java | 31 ++
.../mqs/event/MqttUnsubscribeEvent.java | 32 ++
.../listener/MqttCloseEventListener.java | 81 +++++
.../listener/MqttConnectEventListener.java | 81 +++++
.../listener/MqttDisconnectEventListener.java | 81 +++++
.../event/listener/MqttPingEventListener.java | 32 ++
.../listener/MqttPublishEventListener.java | 58 ++++
.../listener/MqttSubscribeEventListener.java | 38 ++
.../MqttUnsubscribeEventListener.java | 38 ++
.../event/publisher/MqttEventPublisher.java | 59 ++++
.../handler/kafka/KafkaProducerService.java | 49 +++
.../handler/kafka/KafkaSendResultHandler.java | 34 ++
.../MqttMessageKafkaConsumerHandler.java | 131 +++++++
.../kafka/MyKafkaListenerErrorHandler.java | 38 ++
.../mqs/mqtt/handler/AddSubDeviceHandler.java | 118 +++++++
.../mqtt/handler/CommandResponseHandler.java | 78 +++++
.../mqs/mqtt/handler/DefaultHandler.java | 28 ++
.../mqtt/handler/DeleteSubDeviceHandler.java | 110 ++++++
.../mqs/mqtt/handler/DeviceDatasHandler.java | 326 ++++++++++++++++++
.../handler/OtaCommandResponseHandler.java | 88 +++++
.../mqs/mqtt/handler/QueryDeviceHandler.java | 116 +++++++
.../mqs/mqtt/handler/SecretKeyHandler.java | 86 +++++
.../broker/mqs/mqtt/handler/TopicHandler.java | 19 +
.../mqtt/handler/UpdateSubDeviceHandler.java | 109 ++++++
.../mqtt/handler/event/MqttMessageEvent.java | 91 +++++
.../factory/AbstractMessageHandler.java | 85 +++++
.../handler/factory/TopicHandlerFactory.java | 106 ++++++
.../handler/listener/MqttMessageListener.java | 48 +++
.../mqtt/service/MqttEventActionService.java | 60 ++++
.../mqtt/service/MqttEventCommandService.java | 62 ++++
.../MqttEventOtaCommandResponseService.java | 75 ++++
.../broker/service/MqttBrokerService.java | 6 +-
.../service/impl/MqttBrokerServiceImpl.java | 38 +-
.../src/main/resources/bootstrap.yml | 2 +
.../thinglinks-modules-link/pom.xml | 7 -
.../common/asyncthread/LinkAsyncConfig.java | 4 +-
.../link/common/cache/CacheSuperAbstract.java | 11 +
.../common/cache/helper/CacheDataHelper.java | 112 ++++++
.../cache/service/DeviceCacheService.java | 133 +++++++
.../DeviceActionMessageKafkaConsumer.java | 21 +-
.../DeviceActionMessageRocketmqConsumer.java | 1 +
.../listener/RedisKeyExpirationListener.java | 5 +-
.../controller/device/DeviceController.java | 186 +++++++++-
.../device/impl/DeviceActionServiceImpl.java | 8 +-
.../device/impl/DeviceDatasServiceImpl.java | 31 +-
.../device/impl/DeviceInfoServiceImpl.java | 4 +-
.../device/impl/DeviceServiceImpl.java | 13 +-
.../product/impl/ProductServiceImpl.java | 13 +-
.../protocol/impl/ProtocolServiceImpl.java | 7 +-
.../thinglinks-modules-rule/pom.xml | 8 +
.../RuleTriggerMessageRocketmqConsumer.java | 7 +-
...eateSuperTableMessageRocketmqConsumer.java | 14 +-
128 files changed, 6504 insertions(+), 394 deletions(-)
rename thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/domain/{model/PublishMessageRequest.java => vo/PublishMessageRequestVO.java} (93%)
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/device/DeviceCacheVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductCacheVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/DeviceActionTypeEnum.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/CommandIssueRequestParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/DeviceCommandWrapperParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OpenAiChatRequestParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OtaCommandRequestParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OtaCommandResponseParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoAddSubDeviceParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoDeleteSubDeviceParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoDeviceDataReportParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoQueryDeviceParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoUpdateSubDeviceStatusParam.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/DeviceCommandResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/OpenAiChatResponseResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/ProtocolDataMessageResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoAddDeviceResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoDeviceOperationResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoQueryDeviceResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/SuperTableDescribeVO.java
delete mode 100644 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceConnectStatus.java
create mode 100644 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceConnectStatusEnum.java
create mode 100644 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerGroupConstant.java
create mode 100644 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerTopicConstant.java
create mode 100644 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/AesUtils.java
create mode 100644 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/SHA256Utils.java
create mode 100644 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/Sm4Utils.java
create mode 100644 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/SnowflakeIdUtil.java
create mode 100755 thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/bean/BeanPlusUtil.java
delete mode 100644 thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/constant/ConsumerTopicConstant.java
create mode 100644 thinglinks-common/thinglinks-common-protocol/README.md
create mode 100644 thinglinks-common/thinglinks-common-protocol/pom.xml
create mode 100644 thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/factory/ProtocolMessageAdapter.java
create mode 100644 thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/model/EncryptionDetailsDTO.java
create mode 100644 thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/model/ProtocolDataMessageDTO.java
create mode 100644 thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/utils/ProtocolMessageSignatureVerifierUtils.java
create mode 100644 thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/utils/ProtocolRegexTopicVariableExtractorUtils.java
create mode 100644 thinglinks-common/thinglinks-common-protocol/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
delete mode 100644 thinglinks-common/thinglinks-common-rocketmq/src/main/java/com/mqttsnet/thinglinks/common/rocketmq/constant/ConsumerGroupConstant.java
delete mode 100644 thinglinks-common/thinglinks-common-rocketmq/src/main/java/com/mqttsnet/thinglinks/common/rocketmq/constant/ConsumerTopicConstant.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/common/asyncthread/BrokerAsyncConfig.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaConsumerConfig.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaProviderConfig.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttCloseEvent.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttConnectEvent.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttDisconnectEvent.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPingEvent.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPublishEvent.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttSubscribeEvent.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttUnsubscribeEvent.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttCloseEventListener.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttConnectEventListener.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttDisconnectEventListener.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPingEventListener.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPublishEventListener.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttSubscribeEventListener.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttUnsubscribeEventListener.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/publisher/MqttEventPublisher.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaProducerService.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaSendResultHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MqttMessageKafkaConsumerHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MyKafkaListenerErrorHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/AddSubDeviceHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/CommandResponseHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DefaultHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeleteSubDeviceHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeviceDatasHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/OtaCommandResponseHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/QueryDeviceHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/SecretKeyHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/TopicHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/UpdateSubDeviceHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/event/MqttMessageEvent.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/AbstractMessageHandler.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/TopicHandlerFactory.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/listener/MqttMessageListener.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventActionService.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventCommandService.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventOtaCommandResponseService.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/CacheSuperAbstract.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/helper/CacheDataHelper.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
diff --git a/doc/sql/changeRecord/1.2.0.RELEASE.sql b/doc/sql/changeRecord/1.2.0.RELEASE.sql
index 83f0b36d..ccdad5f8 100644
--- a/doc/sql/changeRecord/1.2.0.RELEASE.sql
+++ b/doc/sql/changeRecord/1.2.0.RELEASE.sql
@@ -1,3 +1,14 @@
+# 设备表新增字段
+ALTER TABLE thinglinks_test.device ADD encrypt_key varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '加密密钥';
+ALTER TABLE thinglinks_test.device ADD encrypt_vector varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '加密向量';
+ALTER TABLE thinglinks_test.device ADD sign_key varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '签名密钥';
+ALTER TABLE thinglinks_test.device ADD encrypt_method tinyint(4) DEFAULT 0 NOT NULL COMMENT '协议加密方式';
+ALTER TABLE thinglinks_test.device ADD sw_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '软件版本';
+ALTER TABLE thinglinks_test.device ADD fw_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '固件版本';
+ALTER TABLE thinglinks_test.device ADD device_sdk_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'v1' NOT NULL COMMENT 'sdk版本';
+
+
+
CREATE TABLE `ota_upgrades`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
@@ -15,7 +26,6 @@ CREATE TABLE `ota_upgrades`
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_by` bigint(20) DEFAULT NULL COMMENT '更新人',
`updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- `created_org_id` bigint(20) DEFAULT NULL COMMENT '创建人组织',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_app_id` (`app_id`) USING BTREE COMMENT '应用ID',
KEY `idx_product_identification` (`product_identification`) USING BTREE COMMENT '产品标识',
@@ -35,7 +45,6 @@ CREATE TABLE `ota_upgrade_tasks`
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_by` bigint(20) DEFAULT NULL COMMENT '更新人',
`updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- `created_org_id` bigint(20) DEFAULT NULL COMMENT '创建人组织',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_upgrade_id` (`upgrade_id`) USING BTREE COMMENT '升级包ID'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='OTA升级任务表';
@@ -55,8 +64,10 @@ CREATE TABLE `ota_upgrade_records`
`failure_details` longtext COMMENT '升级失败详细信息',
`log_details` longtext COMMENT '升级过程日志',
`remark` varchar(255) DEFAULT '' COMMENT '描述',
+ `created_by` bigint(20) DEFAULT NULL COMMENT '创建人',
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
- `created_org_id` bigint(20) DEFAULT NULL COMMENT '创建人组织',
+ `updated_by` bigint(20) DEFAULT NULL COMMENT '更新人',
+ `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `idx_task_id_device_identification` (`task_id`,`device_identification`) USING BTREE,
KEY `idx_task_id` (`task_id`),
diff --git a/doc/sql/thinglinks.sql b/doc/sql/thinglinks.sql
index 270d2165..6d838fee 100644
--- a/doc/sql/thinglinks.sql
+++ b/doc/sql/thinglinks.sql
@@ -450,36 +450,43 @@ COMMIT;
-- Table structure for device
-- ----------------------------
DROP TABLE IF EXISTS `device`;
+-- thinglinks_test.device definition
+
CREATE TABLE `device`
(
`id` bigint(19) NOT NULL AUTO_INCREMENT COMMENT 'id',
- `client_id` varchar(255) NOT NULL COMMENT '客户端标识',
- `user_name` varchar(255) NOT NULL COMMENT '用户名',
- `password` varchar(255) NOT NULL COMMENT '密码',
- `app_id` varchar(64) NOT NULL COMMENT '应用ID',
- `auth_mode` varchar(255) DEFAULT NULL COMMENT '认证方式',
- `device_identification` varchar(100) NOT NULL COMMENT '设备标识',
- `device_name` varchar(255) NOT NULL COMMENT '设备名称',
- `connector` varchar(255) DEFAULT NULL COMMENT '连接实例',
- `device_description` varchar(255) DEFAULT NULL COMMENT '设备描述',
- `device_status` varchar(255) NOT NULL COMMENT '设备状态: 启用 || 禁用',
- `connect_status` varchar(255) DEFAULT NULL COMMENT '连接状态 : 在线:ONLINE || 离线:OFFLINE || 未连接:INIT',
- `is_will` varchar(255) DEFAULT NULL COMMENT '是否遗言',
- `device_tags` varchar(255) DEFAULT NULL COMMENT '设备标签',
- `product_identification` varchar(255) NOT NULL COMMENT '产品标识',
- `protocol_type` varchar(255) NOT NULL COMMENT '产品协议类型 :mqtt || coap || modbus || http',
- `device_type` varchar(255) DEFAULT NULL COMMENT '设备类型',
- `create_by` varchar(64) DEFAULT 'ununited' COMMENT '创建者',
- `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
- `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- `remark` varchar(500) DEFAULT NULL COMMENT '备注',
+ `client_id` varchar(255) NOT NULL COMMENT '客户端标识',
+ `user_name` varchar(255) NOT NULL COMMENT '用户名',
+ `password` varchar(255) NOT NULL COMMENT '密码',
+ `app_id` varchar(64) NOT NULL COMMENT '应用ID',
+ `auth_mode` varchar(255) DEFAULT NULL COMMENT '认证方式',
+ `device_identification` varchar(100) NOT NULL COMMENT '设备标识',
+ `device_name` varchar(255) NOT NULL COMMENT '设备名称',
+ `connector` varchar(255) DEFAULT NULL COMMENT '连接实例',
+ `device_description` varchar(255) DEFAULT NULL COMMENT '设备描述',
+ `device_status` varchar(255) NOT NULL COMMENT '设备状态: 启用 || 禁用',
+ `connect_status` varchar(255) DEFAULT NULL COMMENT '连接状态 : 在线:ONLINE || 离线:OFFLINE || 未连接:INIT',
+ `is_will` varchar(255) DEFAULT NULL COMMENT '是否遗言',
+ `device_tags` varchar(255) DEFAULT NULL COMMENT '设备标签',
+ `product_identification` varchar(255) NOT NULL COMMENT '产品标识',
+ `protocol_type` varchar(255) NOT NULL COMMENT '产品协议类型 :mqtt || coap || modbus || http',
+ `device_type` varchar(255) DEFAULT NULL COMMENT '设备类型',
+ `create_by` varchar(64) DEFAULT 'ununited' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `remark` varchar(500) DEFAULT NULL COMMENT '备注',
+ `encrypt_key` varchar(255) CHARACTER SET utf8mb4 DEFAULT '' COMMENT '加密密钥',
+ `encrypt_vector` varchar(255) CHARACTER SET utf8mb4 DEFAULT '' COMMENT '加密向量',
+ `sign_key` varchar(255) CHARACTER SET utf8mb4 DEFAULT '' COMMENT '签名密钥',
+ `encrypt_method` tinyint(4) NOT NULL DEFAULT '0' COMMENT '协议加密方式',
+ `sw_version` varchar(255) CHARACTER SET utf8mb4 DEFAULT '' COMMENT '软件版本',
+ `fw_version` varchar(255) CHARACTER SET utf8mb4 DEFAULT '' COMMENT '固件版本',
+ `device_sdk_version` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT 'v1' COMMENT 'sdk版本',
PRIMARY KEY (`id`) USING BTREE,
KEY `device_id` (`device_identification`) USING BTREE COMMENT '设备标识',
KEY `client_id` (`client_id`) USING BTREE COMMENT '客户端标识'
-) ENGINE = InnoDB
- AUTO_INCREMENT = 67
- DEFAULT CHARSET = utf8 COMMENT ='边设备档案信息表';
+) ENGINE=InnoDB AUTO_INCREMENT=84 DEFAULT CHARSET=utf8 COMMENT='边设备档案信息表';
-- ----------------------------
-- Records of device
@@ -4321,6 +4328,8 @@ CREATE TABLE `ota_upgrades`
-- Table structure for ota_upgrade_tasks
-- ----------------------------
+-- thinglinks_test.ota_upgrade_tasks definition
+
CREATE TABLE `ota_upgrade_tasks`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
@@ -4334,7 +4343,6 @@ CREATE TABLE `ota_upgrade_tasks`
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_by` bigint(20) DEFAULT NULL COMMENT '更新人',
`updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- `created_org_id` bigint(20) DEFAULT NULL COMMENT '创建人组织',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_upgrade_id` (`upgrade_id`) USING BTREE COMMENT '升级包ID'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='OTA升级任务表';
@@ -4348,6 +4356,7 @@ CREATE TABLE `ota_upgrade_tasks`
-- Table structure for ota_upgrade_records
-- ----------------------------
+
CREATE TABLE `ota_upgrade_records`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
@@ -4363,6 +4372,10 @@ CREATE TABLE `ota_upgrade_records`
`failure_details` longtext COMMENT '升级失败详细信息',
`log_details` longtext COMMENT '升级过程日志',
`remark` varchar(255) DEFAULT '' COMMENT '描述',
+ `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
+ `created_by` bigint(20) DEFAULT NULL COMMENT '创建人',
+ `updated_by` bigint(20) DEFAULT NULL COMMENT '更新人',
+ `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `idx_task_id_device_identification` (`task_id`,`device_identification`) USING BTREE,
KEY `idx_task_id` (`task_id`),
diff --git a/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/RemoteMqttBrokerOpenApi.java b/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/RemoteMqttBrokerOpenApi.java
index 881a406e..eaada038 100644
--- a/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/RemoteMqttBrokerOpenApi.java
+++ b/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/RemoteMqttBrokerOpenApi.java
@@ -1,6 +1,6 @@
package com.mqttsnet.thinglinks.broker.api;
-import com.mqttsnet.thinglinks.broker.api.domain.model.PublishMessageRequest;
+import com.mqttsnet.thinglinks.broker.api.domain.vo.PublishMessageRequestVO;
import com.mqttsnet.thinglinks.broker.api.factory.RemoteMqttBrokerOpenApiFallback;
import com.mqttsnet.thinglinks.common.core.constant.ServiceNameConstants;
import com.mqttsnet.thinglinks.common.core.domain.R;
@@ -30,12 +30,12 @@ public interface RemoteMqttBrokerOpenApi {
/**
* MQTT推送消息接口
*
- * @param publishMessageRequest 推送消息请求参数
+ * @param publishMessageRequestVO 推送消息请求参数
* @return {@link R} 结果
*/
@ApiOperation(value = "MQTT推送消息", notes = "根据提供的主题、服务质量等级、保留标志和消息内容推送MQTT消息")
@PostMapping("/sendMessage")
- R> sendMessage(@ApiParam(value = "推送消息请求参数", required = true) @RequestBody PublishMessageRequest publishMessageRequest);
+ R> sendMessage(@ApiParam(value = "推送消息请求参数", required = true) @RequestBody PublishMessageRequestVO publishMessageRequestVO);
/**
* 关闭客户端连接
diff --git a/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/domain/model/PublishMessageRequest.java b/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/domain/vo/PublishMessageRequestVO.java
similarity index 93%
rename from thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/domain/model/PublishMessageRequest.java
rename to thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/domain/vo/PublishMessageRequestVO.java
index 7d19aad8..2fd9a069 100644
--- a/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/domain/model/PublishMessageRequest.java
+++ b/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/domain/vo/PublishMessageRequestVO.java
@@ -1,4 +1,4 @@
-package com.mqttsnet.thinglinks.broker.api.domain.model;
+package com.mqttsnet.thinglinks.broker.api.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -23,7 +23,7 @@
@EqualsAndHashCode
@Builder
@ApiModel(value = "PublishMessageRequestVO", description = "MQTT 发送消息VO")
-public class PublishMessageRequest implements Serializable {
+public class PublishMessageRequestVO implements Serializable {
private static final long serialVersionUID = 1L;
diff --git a/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/factory/RemoteMqttBrokerOpenApiFallback.java b/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/factory/RemoteMqttBrokerOpenApiFallback.java
index c1f2b7c9..71ab86ae 100644
--- a/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/factory/RemoteMqttBrokerOpenApiFallback.java
+++ b/thinglinks-api/thinglinks-api-broker/src/main/java/com/mqttsnet/thinglinks/broker/api/factory/RemoteMqttBrokerOpenApiFallback.java
@@ -1,7 +1,7 @@
package com.mqttsnet.thinglinks.broker.api.factory;
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
-import com.mqttsnet.thinglinks.broker.api.domain.model.PublishMessageRequest;
+import com.mqttsnet.thinglinks.broker.api.domain.vo.PublishMessageRequestVO;
import com.mqttsnet.thinglinks.common.core.domain.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,11 +34,11 @@ public RemoteMqttBrokerOpenApi create(Throwable throwable) {
/**
* MQTT推送消息接口
*
- * @param publishMessageRequest 推送消息请求参数
+ * @param publishMessageRequestVO 推送消息请求参数
* @return {@link R} 结果
*/
@Override
- public R> sendMessage(PublishMessageRequest publishMessageRequest) {
+ public R> sendMessage(PublishMessageRequestVO publishMessageRequestVO) {
return R.fail("remoteMqttBrokerOpenApi.sendMessage() Service call failure e:{}", throwable.getMessage());
}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceService.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceService.java
index 7b911a93..00e2b08a 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceService.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceService.java
@@ -3,10 +3,17 @@
import com.mqttsnet.thinglinks.common.core.constant.ServiceNameConstants;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
import com.mqttsnet.thinglinks.link.api.factory.RemoteDeviceFallbackFactory;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
+import javax.validation.Valid;
import java.util.List;
import java.util.Map;
@@ -55,10 +62,11 @@ public interface RemoteDeviceService {
*/
@GetMapping("/device/selectByProductIdentificationAndDeviceIdentification/{productIdentification}/{deviceIdentification}")
public R selectByProductIdentificationAndDeviceIdentification(@PathVariable("productIdentification") String productIdentification,
- @PathVariable("deviceIdentification") String deviceIdentification);
+ @PathVariable("deviceIdentification") String deviceIdentification);
/**
* 根据客户端标识获取设备信息
+ *
* @param clientId
* @return
*/
@@ -67,6 +75,7 @@ public R selectByProductIdentificationAndDeviceIdentification(@PathVaria
/**
* 根据产品标识获取产品所有关联设备
+ *
* @param productIdentification
* @return
*/
@@ -75,4 +84,136 @@ public R selectByProductIdentificationAndDeviceIdentification(@PathVaria
@PostMapping("/device/selectDeviceByDeviceIdentificationList")
public R> selectDeviceByDeviceIdentificationList(@RequestBody List deviceIdentificationList);
+
+ /**
+ * (MQTT)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @ApiOperation(value = "(MQTT)协议新增子设备档案", httpMethod = "POST", notes = "(MQTT)协议新增子设备档案")
+ @PostMapping("/saveSubDeviceByMqtt")
+ R saveSubDeviceByMqtt(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam);
+
+
+ /**
+ * (HTTP)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @ApiOperation(value = "(HTTP)协议新增子设备档案", httpMethod = "POST", notes = "(HTTP)协议新增子设备档案")
+ @PostMapping("/saveSubDeviceByHttp")
+ public R saveSubDeviceByHttp(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam);
+
+
+ /**
+ * MQTT协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(MQTT)协议修改子设备连接状态", httpMethod = "PUT", notes = "(MQTT)协议修改子设备连接状态")
+ @PutMapping("/updateSubDeviceConnectStatusByMqtt")
+ R updateSubDeviceConnectStatusByMqtt(@RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam);
+
+
+ /**
+ * HTTP协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(HTTP)协议修改子设备连接状态", httpMethod = "PUT", notes = "(HTTP)协议修改子设备连接状态")
+ @PutMapping("/updateSubDeviceConnectStatusByHttp")
+ R updateSubDeviceConnectStatusByHttp(@RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam);
+
+ /**
+ * MQTT协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(MQTT)协议删除子设备", httpMethod = "PUT", notes = "(MQTT)协议删除子设备")
+ @PutMapping("/deleteSubDeviceByMqtt")
+ R deleteSubDeviceByMqtt(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam);
+
+
+ /**
+ * HTTP协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(HTTP)协议删除子设备", httpMethod = "PUT", notes = "(HTTP)协议删除子设备")
+ @PutMapping("/deleteSubDeviceByHttp")
+ R deleteSubDeviceByHttp(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam);
+
+
+ /**
+ * MQTT协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @ApiOperation(value = "(MQTT)协议数据上报", httpMethod = "PUT", notes = "(MQTT)协议数据上报")
+ @PostMapping("/deviceDataReportByMqtt")
+ R deviceDataReportByMqtt(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam);
+
+ /**
+ * HTTP协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @ApiOperation(value = "(HTTP)协议数据上报", httpMethod = "PUT", notes = "(HTTP)协议数据上报")
+ @PostMapping("/deviceDataReportByHttp")
+ R deviceDataReportByHttp(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam);
+
+ /**
+ * Queries device information using the MQTT protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @ApiOperation(value = "Query Device Information via MQTT Protocol", httpMethod = "POST", notes = "Queries device information using the MQTT protocol")
+ @PostMapping("/queryDeviceByMqtt")
+ public R queryDeviceByMqtt(@RequestBody TopoQueryDeviceParam topoQueryDeviceParam);
+
+ /**
+ * Queries device information using the HTTP protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @ApiOperation(value = "Query Device Information via HTTP Protocol", httpMethod = "POST", notes = "Queries device information using the HTTP protocol")
+ @PostMapping("/queryDeviceByHttp")
+ public R queryDeviceByHttp(@RequestBody TopoQueryDeviceParam topoQueryDeviceParam);
+
+
+ /**
+ * Receives and saves a new OTA upgrade record from an MQTT message. This endpoint
+ * captures the command response parameters from the MQTT message body and persists them.
+ *
+ * @param otaCommandResponseParam The response parameters from an OTA command sent via MQTT.
+ * @return {@link R} A response entity containing the saved OTA upgrade record.
+ */
+ @ApiOperation(value = "Save OTA Upgrade Record", httpMethod = "POST", notes = "Saves a new OTA upgrade record from MQTT message data.")
+ @PostMapping("/saveUpgradeRecordByMqtt")
+ public R saveUpgradeRecordByMqtt(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam);
+
+
+ /**
+ * Receives and saves a new OTA upgrade record from an HTTP request. This endpoint
+ * captures the command response parameters from the request body and persists them.
+ *
+ * @param otaCommandResponseParam The response parameters from an OTA command sent via HTTP.
+ * @return {@link R} A response wrapper containing the saved OTA upgrade record.
+ */
+ @ApiOperation(value = "Save OTA Upgrade Record via HTTP", httpMethod = "POST", notes = "Saves a new OTA upgrade record from HTTP request data.")
+ @PostMapping("/saveUpgradeRecordByHttp")
+ public R saveUpgradeRecordByHttp(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam);
+
+
+
}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/device/DeviceCacheVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/device/DeviceCacheVO.java
new file mode 100644
index 00000000..f8c8c28d
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/device/DeviceCacheVO.java
@@ -0,0 +1,41 @@
+package com.mqttsnet.thinglinks.link.api.domain.cache.device;
+
+import cn.hutool.core.map.MapUtil;
+import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ *
+ * 设备档案缓存VO
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "DeviceCacheVO", description = "设备档案缓存VO")
+public class DeviceCacheVO extends Device implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+ /**
+ * 设备产品基础信息
+ */
+ @ApiModelProperty(value = "设备产品基础信息")
+ private ProductCacheVO productCacheVO;
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductCacheVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductCacheVO.java
new file mode 100644
index 00000000..2c00f490
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductCacheVO.java
@@ -0,0 +1,35 @@
+package com.mqttsnet.thinglinks.link.api.domain.cache.product;
+
+import cn.hutool.core.map.MapUtil;
+import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
+import io.swagger.annotations.ApiModel;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ *
+ * 产品模型缓存VO
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = true)
+@Builder
+@ApiModel(value = "ProductCacheVO", description = "产品模型缓存VO")
+public class ProductCacheVO extends Product implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
new file mode 100644
index 00000000..940fe0cb
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
@@ -0,0 +1,29 @@
+package com.mqttsnet.thinglinks.link.api.domain.cache.product;
+
+import com.mqttsnet.thinglinks.link.api.domain.product.model.ProductModel;
+import io.swagger.annotations.ApiModel;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 产品模型缓存VO
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "ProductModelCacheVO", description = "产品模型缓存VO")
+public class ProductModelCacheVO extends ProductModel implements Serializable {
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/Device.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/Device.java
index c7f2d592..b567a462 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/Device.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/Device.java
@@ -6,8 +6,9 @@
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
+
+import lombok.*;
+import lombok.experimental.Accessors;
/**
@@ -29,6 +30,11 @@
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "设备管理")
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class Device extends BaseEntity implements Serializable{
/**
* id
@@ -150,6 +156,50 @@ public class Device extends BaseEntity implements Serializable{
@ApiModelProperty(value = "设备类型")
private String deviceType;
+ /**
+ * 加密密钥
+ */
+ @Excel(name = "加密密钥")
+ @ApiModelProperty(value = "加密密钥")
+ private String encryptKey;
+ /**
+ * 加密向量
+ */
+ @Excel(name = "加密向量")
+ @ApiModelProperty(value = "加密向量")
+ private String encryptVector;
+ /**
+ * 签名密钥
+ */
+ @Excel(name = "签名密钥")
+ @ApiModelProperty(value = "签名密钥")
+ private String signKey;
+ /**
+ * 传输协议的加密方式:0-明文传输、1-SM4、2-AES
+ */
+ @Excel(name = "传输协议的加密方式")
+ @ApiModelProperty(value = "传输协议的加密方式:0-明文传输、1-SM4、2-AES ")
+ private Integer encryptMethod;
+
+ /**
+ * 软件版本
+ */
+ @Excel(name = "软件版本")
+ @ApiModelProperty(value = "软件版本")
+ private String swVersion;
+ /**
+ * 固件版本
+ */
+ @Excel(name = "固件版本")
+ @ApiModelProperty(value = "固件版本")
+ private String fwVersion;
+ /**
+ * sdk版本
+ */
+ @Excel(name = "sdk版本")
+ @ApiModelProperty(value = "sdk版本")
+ private String deviceSdkVersion;
+
private static final long serialVersionUID = 1L;
}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceAction.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceAction.java
index e2259348..e4101219 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceAction.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceAction.java
@@ -4,7 +4,9 @@
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
-import lombok.Data;
+
+import lombok.*;
+import lombok.experimental.Accessors;
/**
@@ -24,6 +26,11 @@
*/
@ApiModel(value="设备动作数据")
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class DeviceAction implements Serializable {
/**
* id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceDatas.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceDatas.java
index 821a88c1..d71f3d42 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceDatas.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceDatas.java
@@ -2,7 +2,8 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
+import lombok.*;
+import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -25,6 +26,11 @@
*/
@ApiModel(value="设备消息")
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class DeviceDatas implements Serializable {
/**
* id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceLocation.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceLocation.java
index a5a29842..8eb45caf 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceLocation.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceLocation.java
@@ -3,9 +3,8 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.*;
+import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
@@ -28,8 +27,11 @@
*/
@ApiModel(value = "设备位置表")
@Data
-@AllArgsConstructor
@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class DeviceLocation implements Serializable {
/**
* 主键
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceTopic.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceTopic.java
index 487aa3d3..143eff06 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceTopic.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/entity/DeviceTopic.java
@@ -2,7 +2,8 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
+import lombok.*;
+import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -20,6 +21,11 @@
*/
@ApiModel(value="设备Topic数据表")
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class DeviceTopic implements Serializable {
/**
* id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/DeviceActionTypeEnum.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/DeviceActionTypeEnum.java
new file mode 100644
index 00000000..61f4da53
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/DeviceActionTypeEnum.java
@@ -0,0 +1,54 @@
+package com.mqttsnet.thinglinks.link.api.domain.device.enumeration;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ *
+ * 设备动作类型 枚举
+ *
+ *
+ * @author shihuan sun
+ * @date 2023-08-20
+ */
+@Getter
+@NoArgsConstructor
+@ApiModel(value = "DeviceActionTypeEnum", description = "设备动作类型 枚举")
+public enum DeviceActionTypeEnum {
+
+ PUBLISH("PUBLISH", "Publishing data to a topic."),
+ WRITE("WRITE", "Writing data to a device or topic."),
+
+ CLUSTER("CLUSTER", "Cluster-based actions or references to clusters."),
+ CONNECT("CONNECT", "Initiating a connection to a server."),
+ CLOSE("CLOSE", "Closing a connection to a server."),
+
+ SUBSCRIBE("SUBSCRIBE", "Subscribing to a topic to receive messages."),
+
+ UNSUBSCRIBE("UNSUBSCRIBE", "Unsubscribing from a topic to stop receiving messages."),
+
+ BRIDGE("BRIDGE", "Bridging or connecting two different networks or brokers."),
+ DISCONNECT("DISCONNECT", "Terminating a connection gracefully."),
+ PING("PING", "Sending a ping request to maintain or check a connection."),
+
+ PUBLISH_ACK("PUBLISH_ACK", "Acknowledging the receipt of a published message."),
+
+ RETRY("RETRY", "Retrying a certain action or request after a failure."),
+
+ HEART_TIMEOUT("HEART_TIMEOUT", "An event indicating a timeout due to lack of heartbeat or keep-alive signal."),
+
+ SYSTEM("SYSTEM", "System level or internal events."),
+
+ UNKNOWN("UNKNOWN", "Unknown action type.");
+
+ private String action;
+ private String description;
+
+ DeviceActionTypeEnum(String action, String description) {
+ this.action = action;
+ this.description = description;
+ }
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/deviceInfo/entity/DeviceInfo.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/deviceInfo/entity/DeviceInfo.java
index 89d7da2c..340a2dff 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/deviceInfo/entity/DeviceInfo.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/deviceInfo/entity/DeviceInfo.java
@@ -5,9 +5,8 @@
import com.mqttsnet.thinglinks.link.api.domain.deviceInfo.model.DeviceInfoParams;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.*;
+import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -25,8 +24,11 @@
*/
@ApiModel(value="子设备档案表")
@Data
-@AllArgsConstructor
@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class DeviceInfo implements Serializable {
/**
* 主键
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/Product.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/Product.java
index 16e9ca85..28f2a57b 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/Product.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/Product.java
@@ -2,9 +2,8 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.*;
+import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -23,8 +22,11 @@
*/
@ApiModel(value = "产品模型")
@Data
-@AllArgsConstructor
@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class Product implements Serializable {
/**
* id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommands.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommands.java
index 6e99e5d5..70838488 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommands.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommands.java
@@ -5,7 +5,9 @@
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
-import lombok.Data;
+
+import lombok.*;
+import lombok.experimental.Accessors;
/**
@@ -25,6 +27,11 @@
*/
@ApiModel(value="产品模型设备服务命令表")
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class ProductCommands extends BaseEntity implements Serializable {
/**
* 命令id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommandsRequests.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommandsRequests.java
index 3a5d41c6..b42b2b3d 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommandsRequests.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommandsRequests.java
@@ -7,7 +7,8 @@
import java.io.Serializable;
import java.time.LocalDateTime;
-import lombok.Data;
+import lombok.*;
+import lombok.experimental.Accessors;
/**
* @Description: java类作用描述
@@ -26,6 +27,11 @@
*/
@ApiModel(value = "产品模型设备下发服务命令属性表")
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class ProductCommandsRequests extends BaseEntity implements Serializable {
/**
* id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommandsResponse.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommandsResponse.java
index af3ceb58..39556d19 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommandsResponse.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductCommandsResponse.java
@@ -3,7 +3,8 @@
import com.mqttsnet.thinglinks.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
+import lombok.*;
+import lombok.experimental.Accessors;
import java.io.Serializable;
@@ -25,6 +26,11 @@
*/
@ApiModel(value="产品模型设备响应服务命令属性表")
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class ProductCommandsResponse extends BaseEntity implements Serializable {
/**
* id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductProperties.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductProperties.java
index eb3c012e..f079648a 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductProperties.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductProperties.java
@@ -5,7 +5,9 @@
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
-import lombok.Data;
+
+import lombok.*;
+import lombok.experimental.Accessors;
/**
@@ -25,6 +27,11 @@
*/
@ApiModel(value="产品模型服务属性表")
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class ProductProperties extends BaseEntity implements Serializable {
/**
* 属性id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductServices.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductServices.java
index af7dcd2e..7002fbb5 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductServices.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductServices.java
@@ -4,9 +4,9 @@
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+
+import lombok.*;
+import lombok.experimental.Accessors;
/**
* @program: thinglinks
@@ -22,8 +22,11 @@
*/
@ApiModel(value = "产品模型服务表")
@Data
-@AllArgsConstructor
@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class ProductServices implements Serializable {
/**
* 服务id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductTemplate.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductTemplate.java
index 29f8bda6..550d367e 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductTemplate.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductTemplate.java
@@ -4,9 +4,9 @@
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+
+import lombok.*;
+import lombok.experimental.Accessors;
/**
* @program: thinglinks
@@ -22,8 +22,11 @@
*/
@ApiModel(value = "产品模板")
@Data
-@AllArgsConstructor
@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class ProductTemplate implements Serializable {
/**
* id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/protocol/Protocol.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/protocol/Protocol.java
index a74aba3e..457a3d4a 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/protocol/Protocol.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/protocol/Protocol.java
@@ -2,9 +2,8 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.*;
+import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -23,8 +22,11 @@
*/
@ApiModel(value="协议信息表")
@Data
-@AllArgsConstructor
@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
public class Protocol implements Serializable {
/**
* id
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/CommandIssueRequestParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/CommandIssueRequestParam.java
new file mode 100644
index 00000000..563ca6d3
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/CommandIssueRequestParam.java
@@ -0,0 +1,64 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * -----------------------------------------------------------------------------
+ * 文件名称: CommandIssueRequestParam.java
+ * -----------------------------------------------------------------------------
+ * 描述:
+ * Platform Command Issue Request Data Model
+ * -----------------------------------------------------------------------------
+ *
+ * @author ShiHuan Sun
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * 修改历史:
+ * 日期 作者 版本 描述
+ * -------- -------- ------- --------------------
+ *
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023-10-17 09:48
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Builder
+@ApiModel(value = "CommandIssueRequestParam", description = "Device Command Request Data Structure")
+public class CommandIssueRequestParam implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "Device unique identifier, ALL for all devices.", notes = "Device unique ID generated by the platform.")
+ @NotEmpty(message = "Device ID cannot be empty")
+ private String deviceIdentification;
+
+ @ApiModelProperty(value = "Product unique identifier.", notes = "Product unique ID generated by the platform.")
+ @NotEmpty(message = "Product ID cannot be empty")
+ private String productIdentification;
+
+ @ApiModelProperty(value = "Fixed value 'cloudReq', indicating the request issued by the platform.", notes = "Fixed value 'cloudReq', indicating the request issued by the platform.")
+ @NotEmpty(message = "Message type cannot be empty")
+ private String msgType;
+
+ @ApiModelProperty(value = "Service code.", notes = "Service code.")
+ @NotEmpty(message = "Service code cannot be empty")
+ private String serviceCode;
+
+ @ApiModelProperty(value = "Command code for the service.", notes = "Command code for the service.")
+ @NotEmpty(message = "Command cannot be empty")
+ private String cmd;
+
+ @ApiModelProperty(value = "Parameters for the command.", notes = "Parameters for the command.")
+ @NotNull(message = "Parameters cannot be null")
+ private Map params;
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/DeviceCommandWrapperParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/DeviceCommandWrapperParam.java
new file mode 100644
index 00000000..550d481b
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/DeviceCommandWrapperParam.java
@@ -0,0 +1,44 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: DeviceCommandWrapperParam.java
+ * -----------------------------------------------------------------------------
+ * Description:
+ * Device Command Request Wrapper Data Structure
+ * -----------------------------------------------------------------------------
+ *
+ * @author ShiHuan Sun
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ *
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023-11-11 14:55
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Builder
+@ApiModel(value = "DeviceCommandWrapperParam", description = "Device Command Request Wrapper Data Structure")
+public class DeviceCommandWrapperParam implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "List of serial command requests", notes = "List of serial command requests")
+ private List serial;
+
+ @ApiModelProperty(value = "List of parallel command requests", notes = "List of parallel command requests")
+ private List parallel;
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OpenAiChatRequestParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OpenAiChatRequestParam.java
new file mode 100644
index 00000000..28809008
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OpenAiChatRequestParam.java
@@ -0,0 +1,60 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: OpenAiChatRequestParam
+ * -----------------------------------------------------------------------------
+ * Description:
+ * OpenAiChatRequest
+ * -----------------------------------------------------------------------------
+ *
+ * @author xiaonannet
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ * 2023/12/12 xiaonannet 1.0 Initial creation
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023/12/12 23:20
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "OpenAiChatRequest", description = "Request parameters for OpenAI Chat API")
+public class OpenAiChatRequestParam implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "The unique session ID generated by OpenAI.", notes = "Specify the id to use for this callback.")
+ private String id;
+
+ @ApiModelProperty(value = "The model to use for this chat (e.g., gpt-3.5-turbo)", notes = "Specifies the model to be used by the API.")
+ @NotEmpty(message = "Model is required")
+ private String model;
+
+ @ApiModelProperty(value = "Content of the message to be processed", notes = "Message content to be sent to OpenAI Chat.")
+ @NotEmpty(message = "Content cannot be null")
+ @Size(min = 1, max = 1000, message = "Content must be between 1 and 1000 characters")
+ private String content;
+
+ @ApiModelProperty(value = "API Key for OpenAI", notes = "The API Key for authentication with OpenAI services.")
+ private String apiKey;
+
+ @ApiModelProperty(value = "API Host for OpenAI", notes = "The host URL for OpenAI services.")
+ private String apiHost;
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OtaCommandRequestParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OtaCommandRequestParam.java
new file mode 100644
index 00000000..d7d33fbb
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OtaCommandRequestParam.java
@@ -0,0 +1,62 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: OtaCommandResponseParam
+ * -----------------------------------------------------------------------------
+ * Description:
+ * OTA 远程升级请求参数
+ * 用于物联网平台向设备发送 OTA 升级指令
+ * -----------------------------------------------------------------------------
+ *
+ * @author xiaonannet
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ * 2024/1/18 xiaonannet 1.0 Initial creation
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2024/1/18 22:28
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel(value = "OtaCommandRequestParam", description = "Request Data Structure for OTA Command")
+public class OtaCommandRequestParam implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "Unique identifier for the device", notes = "Unique identifier for the device, as generated by the platform.")
+ private String deviceIdentification;
+
+ @ApiModelProperty(value = "Unique identifier for the product", notes = "Unique identifier for the product, as generated by the platform.")
+ private String productIdentification;
+
+ @ApiModelProperty(value = "Unique identifier for the OTA task", notes = "Unique identifier for the OTA task, as assigned by the platform.")
+ private Long otaTaskId;
+
+ @ApiModelProperty(value = "Type of OTA package", notes = "The type of OTA package, e.g., 0 for software, 1 for firmware.")
+ private Integer packageType;
+
+ @ApiModelProperty(value = "Version of the OTA package", notes = "The version of the OTA package. Should not exceed 256 characters and may include letters, numbers, underscores (_), hyphens (-), and periods (.)")
+ private String version;
+
+ @ApiModelProperty(value = "Location of the OTA package file", notes = "The file path or location where the OTA package is stored, accessible within 24 hours.")
+ private String fileLocation;
+
+ @ApiModelProperty(value = "Description of the OTA package", notes = "A brief description of the OTA package's functionality.")
+ private String description;
+
+ @ApiModelProperty(value = "Custom information for the OTA package", notes = "Additional custom information related to the OTA package, if any.")
+ private String customInfo;
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OtaCommandResponseParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OtaCommandResponseParam.java
new file mode 100644
index 00000000..c84e1036
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/OtaCommandResponseParam.java
@@ -0,0 +1,71 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: OtaCommandResponseParam
+ * -----------------------------------------------------------------------------
+ * Description:
+ * OTA 远程升级响应参数
+ * 用于设备向物联网平台上报 OTA 升级结果
+ * -----------------------------------------------------------------------------
+ *
+ * @author xiaonannet
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ * 2024/1/18 xiaonannet 1.0 Initial creation
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2024/1/18 22:28
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel(value = "OtaCommandResponseParam", description = "Response Data Structure for OTA Command")
+public class OtaCommandResponseParam implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "The unique identifier of the device.")
+ private String deviceIdentification;
+
+ @ApiModelProperty(value = "The unique identifier of the OTA task.")
+ private Long otaTaskId;
+
+ @ApiModelProperty(value = "The status of the OTA upgrade: 0 for pending, 1 for in progress, 2 for success, 3 for failure.")
+ private Integer upgradeStatus;
+
+ @ApiModelProperty(value = "The progress of the OTA upgrade in percentage.")
+ private Integer progress;
+
+ @ApiModelProperty(value = "The start time of the OTA upgrade as a timestamp.")
+ private Long startTime;
+
+ @ApiModelProperty(value = "The end time of the OTA upgrade as a timestamp.")
+ private Long endTime;
+
+ @ApiModelProperty(value = "The error code, if any, resulting from the OTA upgrade.")
+ private String errorCode;
+
+ @ApiModelProperty(value = "The error message, if any, resulting from the OTA upgrade.")
+ private String errorMessage;
+
+ @ApiModelProperty(value = "Details about the success of the OTA upgrade.")
+ private String successDetails;
+
+ @ApiModelProperty(value = "Details about the failure of the OTA upgrade.")
+ private String failureDetails;
+
+ @ApiModelProperty(value = "Logs detailing the OTA upgrade process.")
+ private String logDetails;
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoAddSubDeviceParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoAddSubDeviceParam.java
new file mode 100644
index 00000000..3d18925a
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoAddSubDeviceParam.java
@@ -0,0 +1,65 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: 网关设备添加子设备数据模型
+ * @Author: ShiHuan SUN
+ * @E-mail: 13733918655@163.com
+ * @Website: http://thinglinks.mqttsnet.com
+ * @CreateDate: 2022/4/25$ 12:52$
+ * @UpdateUser: ShiHuan SUN
+ * @UpdateDate: 2022/4/25$ 12:52$
+ * @UpdateRemark: 修改内容
+ * @Version: V1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "TopoAddDeviceSaveVO", description = "网关设备添加子设备数据模型")
+public class TopoAddSubDeviceParam implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "网关设备标识", notes = "网关设备自身的唯一标识")
+ @NotEmpty(message = "网关设备标识不能为空")
+ private String gatewayIdentification;
+
+ @ApiModelProperty(value = "子设备信息集合", notes = "子设备信息集合")
+ @NotNull(message = "子设备信息集合不能为空")
+ private List deviceInfos;
+
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ public static class DeviceInfos {
+
+ @ApiModelProperty(value = "子设备ID", notes = "子设备自身的唯一标识")
+ private String nodeId;
+
+ @ApiModelProperty(value = "子设备名称", notes = "子设备名称")
+ private String name;
+
+ @ApiModelProperty(value = "子设备描述", notes = "子设备描述")
+ private String description;
+
+ @ApiModelProperty(value = "子设备厂商ID", notes = "子设备厂商ID")
+ private String manufacturerId;
+
+ @ApiModelProperty(value = "子设备型号", notes = "子设备型号")
+ private String model;
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoDeleteSubDeviceParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoDeleteSubDeviceParam.java
new file mode 100644
index 00000000..7d242c2a
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoDeleteSubDeviceParam.java
@@ -0,0 +1,42 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: 网关设备删除子设备数据模型
+ * @Author: ShiHuan SUN
+ * @E-mail: 13733918655@163.com
+ * @Website: http://thinglinks.mqttsnet.com
+ * @CreateDate: 2022/4/25$ 12:52$
+ * @UpdateUser: ShiHuan SUN
+ * @UpdateDate: 2022/4/25$ 12:52$
+ * @UpdateRemark: 修改内容
+ * @Version: V1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "TopoDeleteDeviceParam", description = "网关设备删除子设备数据模型")
+public class TopoDeleteSubDeviceParam implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "网关设备标识", notes = "网关设备自身的唯一标识")
+ @NotEmpty(message = "网关设备标识不能为空")
+ private String gatewayIdentification;
+
+ @ApiModelProperty(value = "子设备标识集合", notes = "子设备标识集合")
+ @NotNull(message = "子设备标识集合不能为空")
+ private List deviceIds;
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoDeviceDataReportParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoDeviceDataReportParam.java
new file mode 100644
index 00000000..f94fea2c
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoDeviceDataReportParam.java
@@ -0,0 +1,78 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: 设备数据上报数据模型
+ * @Author: ShiHuan SUN
+ * @E-mail: 13733918655@163.com
+ * @Website: http://thinglinks.mqttsnet.com
+ * @CreateDate: 2022/4/25$ 12:52$
+ * @UpdateUser: ShiHuan SUN
+ * @UpdateDate: 2022/4/25$ 12:52$
+ * @UpdateRemark: 修改内容
+ * @Version: V1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "TopoDeviceDataReportParam", description = "设备数据上报数据模型")
+public class TopoDeviceDataReportParam implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "设备数据", notes = "设备数据")
+ @NotNull(message = "设备数据不能为空")
+ private List devices;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ @Accessors(chain = true)
+ @ApiModel(value = "DeviceS", description = "设备数据模型")
+ public static class DeviceS implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "设备唯一标识", notes = "平台生成的设备唯一标识")
+ @NotEmpty(message = "设备唯一标识不能为空")
+ private String deviceId;
+
+ @ApiModelProperty(value = "服务列表", notes = "服务列表")
+ @NotNull(message = "服务列表不能为空")
+ private List services;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ @Accessors(chain = true)
+ @ApiModel(value = "Services", description = "服务数据模型")
+ public static class Services implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "服务编码", notes = "服务编码,对应平台产品服务编码")
+ @NotEmpty(message = "服务编码不能为空")
+ private String serviceCode;
+
+ @ApiModelProperty(value = "服务数据", notes = "服务数据,不固定内容")
+ @NotNull(message = "服务数据不能为空")
+ private Object data;
+
+ @ApiModelProperty(value = "事件时间", notes = "时间格式:13位毫秒时间戳。例如,1622552643000表示2021年6月1日17时24分3秒(UTC时间)。")
+ @NotEmpty(message = "事件时间不能为空")
+ private Long eventTime;
+ }
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoQueryDeviceParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoQueryDeviceParam.java
new file mode 100644
index 00000000..06f0d3b1
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoQueryDeviceParam.java
@@ -0,0 +1,37 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: 查询设备信息数据模型
+ * @Author: ShiHuan SUN
+ * @E-mail: 13733918655@163.com
+ * @Website: http://thinglinks.mqttsnet.com
+ * @CreateDate: 2022/4/25$ 12:52$
+ * @UpdateUser: ShiHuan SUN
+ * @UpdateDate: 2024/01/10$ 12:52$
+ * @UpdateRemark: 修改内容
+ * @Version: V1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "TopoQueryDeviceParam", description = "查询设备信息数据模型")
+public class TopoQueryDeviceParam implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "设备标识集合", notes = "设备标识集合")
+ @NotNull(message = "设备标识集合不能为空")
+ private List deviceIds;
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoUpdateSubDeviceStatusParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoUpdateSubDeviceStatusParam.java
new file mode 100644
index 00000000..14aa0596
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoUpdateSubDeviceStatusParam.java
@@ -0,0 +1,63 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.param;
+
+import com.mqttsnet.thinglinks.device.enumeration.DeviceConnectStatusEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: 网关设备更新子设备状态数据模型
+ * @Author: ShiHuan SUN
+ * @E-mail: 13733918655@163.com
+ * @Website: http://thinglinks.mqttsnet.com
+ * @CreateDate: 2022/4/25$ 12:52$
+ * @UpdateUser: ShiHuan SUN
+ * @UpdateDate: 2022/4/25$ 12:52$
+ * @UpdateRemark: 修改内容
+ * @Version: V1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "TopoUpdateSubDeviceStatusParam", description = "子设备状态更新数据模型")
+public class TopoUpdateSubDeviceStatusParam implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "网关设备标识", notes = "网关设备自身的唯一标识")
+ @NotEmpty(message = "网关设备标识不能为空")
+ private String gatewayIdentification;
+
+ @ApiModelProperty(value = "子设备状态列表", notes = "子设备状态列表,列表大小 1~100")
+ @NotNull(message = "子设备状态列表不能为空")
+ @Size(min = 1, max = 100, message = "子设备状态列表大小必须在1到100之间")
+ private List deviceStatuses;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ @Accessors(chain = true)
+ @ApiModel(value = "DeviceStatus", description = "子设备状态数据模型")
+ public static class DeviceStatus implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "子设备唯一标识", notes = "平台生成的子设备唯一标识")
+ @NotEmpty(message = "子设备唯一标识不能为空")
+ private String deviceId;
+
+ @ApiModelProperty(value = "子设备状态", notes = "子设备状态:OFFLINE:设备离线;ONLINE:设备上线;")
+ @NotNull(message = "子设备状态不能为空")
+ private DeviceConnectStatusEnum status;
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/DeviceCommandResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/DeviceCommandResultVO.java
new file mode 100644
index 00000000..f71163f9
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/DeviceCommandResultVO.java
@@ -0,0 +1,75 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.result;
+
+import cn.hutool.core.map.MapUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ *
+ * 表单查询方法返回值VO
+ * 设备命令下发及响应表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-10-20 17:27:25
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "DeviceCommandResultVO", description = "设备命令下发及响应表")
+public class DeviceCommandResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+ @ApiModelProperty(value = "id")
+ private Long id;
+
+ /**
+ * 设备标识
+ */
+ @ApiModelProperty(value = "设备标识")
+ private String deviceIdentification;
+ /**
+ * 命令标识
+ */
+ @ApiModelProperty(value = "命令标识")
+ private String commandIdentification;
+ /**
+ * 命令类型(0:命名下发、1:命令响应)
+ */
+ @ApiModelProperty(value = "命令类型(0:命名下发、1:命令响应)")
+ private Integer commandType;
+ /**
+ * 状态
+ */
+ @ApiModelProperty(value = "状态")
+ private Integer status;
+ /**
+ * 内容
+ */
+ @ApiModelProperty(value = "内容")
+ private String content;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/OpenAiChatResponseResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/OpenAiChatResponseResultVO.java
new file mode 100644
index 00000000..b86a00d6
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/OpenAiChatResponseResultVO.java
@@ -0,0 +1,128 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.result;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: OpenAiChatRequestParam
+ * -----------------------------------------------------------------------------
+ * Description:
+ * OpenAiChatRequest
+ * -----------------------------------------------------------------------------
+ *
+ * @author xiaonannet
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ * 2023/12/12 xiaonannet 1.0 Initial creation
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023/12/12 23:20
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "OpenAiChatResponseResultVO", description = "Response data from OpenAI Chat API")
+public class OpenAiChatResponseResultVO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "Unique identifier for the response")
+ private String id;
+
+ @ApiModelProperty(value = "Type of the object returned")
+ private String object;
+
+ @ApiModelProperty(value = "Timestamp of creation")
+ private long created;
+
+ @ApiModelProperty(value = "Model used for generating the response")
+ private String model;
+
+ @ApiModelProperty(value = "List of choices provided by OpenAI")
+ private List choices;
+
+ @ApiModelProperty(value = "Usage information of tokens")
+ private Usage usage;
+
+ @ApiModelProperty(value = "Any warning returned by the API")
+ private String warning;
+
+ @ApiModelProperty(value = "System fingerprint")
+ @JsonProperty("system_fingerprint")
+ private String systemFingerprint;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @ToString
+ @EqualsAndHashCode
+ public static class Usage implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "Number of tokens used in the prompt")
+ @JsonProperty("prompt_tokens")
+ private long promptTokens;
+
+ @ApiModelProperty(value = "Number of tokens used in the completion")
+ @JsonProperty("completion_tokens")
+ private long completionTokens;
+
+ @ApiModelProperty(value = "Total number of tokens used")
+ @JsonProperty("total_tokens")
+ private long totalTokens;
+ }
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @ToString
+ @EqualsAndHashCode
+ public static class ChatChoice implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "Index of the choice")
+ private long index;
+
+ @ApiModelProperty(value = "Message content in delta format (when stream is true)")
+ @JsonProperty("delta")
+ private Message delta;
+
+ @ApiModelProperty(value = "Message content (when stream is false)")
+ @JsonProperty("message")
+ private Message message;
+
+ @ApiModelProperty(value = "Reason for completion")
+ @JsonProperty("finish_reason")
+ private String finishReason;
+
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @ToString
+ @EqualsAndHashCode
+ public static class Message implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "Content of the message")
+ private String content;
+
+ @ApiModelProperty(value = "Role of the message sender (e.g., 'user', 'system')")
+ private String role;
+ }
+ }
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/ProtocolDataMessageResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/ProtocolDataMessageResultVO.java
new file mode 100644
index 00000000..5b0afee6
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/ProtocolDataMessageResultVO.java
@@ -0,0 +1,53 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.result;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 协议数据内容返回VO
+ * @packagename: com.mqttsnet.thinglinks.device.vo.result
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-22 15:44
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
+@ApiModel(value = "ProtocolDataMessageResultVO", description = "协议数据内容返回VO")
+public class ProtocolDataMessageResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "消息头部")
+ private Head head;
+
+ @ApiModelProperty(value = "报文体")
+ private T dataBody;
+
+ @ApiModelProperty(value = "数据签名")
+ private String dataSign;
+
+ @ApiModel(description = "消息头部实体类")
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ public static class Head {
+ @ApiModelProperty(value = "加密标志,0-不加密;1-SM4;2-AES", allowableValues = "0, 1, 2", example = "0")
+ private Integer cipherFlag;
+
+ @ApiModelProperty(value = "消息ID(从1自增即可)", example = "3342")
+ private Long mid;
+
+ @ApiModelProperty(value = "报文发送时间戳(毫秒)", example = "1624982406963")
+ private Long timeStamp;
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoAddDeviceResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoAddDeviceResultVO.java
new file mode 100644
index 00000000..dd7289af
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoAddDeviceResultVO.java
@@ -0,0 +1,79 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.result;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 协议添加网关子设备响应信息
+ * @packagename: com.mqttsnet.thinglinks.device.vo.result
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-18 23:03
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
+@ApiModel(value = "TopoAddDeviceResultVO", description = "网关子设备响应信息")
+public class TopoAddDeviceResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "请求处理的结果码。'0'表示成功。非'0'表示失败。详见附录。", required = true)
+ private int statusCode;
+
+ @ApiModelProperty(value = "响应状态描述。")
+ private String statusDesc;
+
+ @ApiModelProperty(value = "添加子设备的结果信息。", required = true)
+ private List data;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ public static class DataItem {
+
+ @ApiModelProperty(value = "请求处理的结果码。'0'表示成功。非'0'表示失败。详见附录。", required = true)
+ private int statusCode;
+
+ @ApiModelProperty(value = "响应状态描述。")
+ private String statusDesc;
+
+ @ApiModelProperty(value = "设备详细信息")
+ private DeviceInfo deviceInfo;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ public static class DeviceInfo {
+
+ @ApiModelProperty(value = "设备名称", required = true)
+ private String name;
+
+ @ApiModelProperty(value = "厂商ID", required = true)
+ private String manufacturerId;
+
+ @ApiModelProperty(value = "设备描述")
+ private String description;
+
+ @ApiModelProperty(value = "设备型号")
+ private String model;
+
+ @ApiModelProperty(value = "平台生成的设备唯一标识", required = true)
+ private String deviceId;
+
+ @ApiModelProperty(value = "设备自身的唯一标识", required = true)
+ private String nodeId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoDeviceOperationResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoDeviceOperationResultVO.java
new file mode 100644
index 00000000..80aa939b
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoDeviceOperationResultVO.java
@@ -0,0 +1,58 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.result;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 设备操作结果数据模型
+ * @packagename: com.mqttsnet.thinglinks.device.vo.result
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-22 14:17
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Accessors(chain = true)
+@ApiModel(value = "TopoDeviceOperationResultVO", description = "设备操作结果数据ResultVO")
+public class TopoDeviceOperationResultVO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "请求处理的结果码", notes = "“0”表示成功。非“0”表示失败。详见附录。")
+ private Integer statusCode;
+
+ @ApiModelProperty(value = "响应状态描述", notes = "响应状态描述", required = false)
+ private String statusDesc;
+
+ @ApiModelProperty(value = "操作结果信息", notes = "操作结果信息")
+ private List data;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ @Accessors(chain = true)
+ @ApiModel(value = "OperationRsp", description = "操作结果结果数据模型")
+ public static class OperationRsp implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "设备ID", notes = "设备ID,平台生成的设备唯一标识")
+ private String deviceId;
+
+ @ApiModelProperty(value = "请求处理的结果码", notes = "“0”表示成功。非“0”表示失败。详见附录。")
+ private Integer statusCode;
+
+ @ApiModelProperty(value = "响应状态描述", notes = "响应状态描述", required = false)
+ private String statusDesc;
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoQueryDeviceResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoQueryDeviceResultVO.java
new file mode 100644
index 00000000..6adad129
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoQueryDeviceResultVO.java
@@ -0,0 +1,136 @@
+package com.mqttsnet.thinglinks.link.api.domain.vo.result;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 协议查询设备档案信息响应信息
+ * @packagename: com.mqttsnet.thinglinks.device.vo.result
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-18 23:03
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
+@ApiModel(value = "TopoQueryDeviceResultVO", description = "设备档案响应信息")
+public class TopoQueryDeviceResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "请求处理的结果码。'0'表示成功。非'0'表示失败。详见附录。", required = true)
+ private int statusCode;
+
+ @ApiModelProperty(value = "响应状态描述。")
+ private String statusDesc;
+
+ @ApiModelProperty(value = "查询设备的结果信息。", required = true)
+ private List data;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ public static class DataItem {
+
+ @ApiModelProperty(value = "请求处理的结果码。'0'表示成功。非'0'表示失败。详见附录。", required = true)
+ private int statusCode;
+
+ @ApiModelProperty(value = "响应状态描述。")
+ private String statusDesc;
+
+ @ApiModelProperty(value = "平台生成的设备唯一标识", required = true)
+ private String deviceId;
+
+ @ApiModelProperty(value = "设备详细信息")
+ private DeviceInfo deviceInfo;
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ public static class DeviceInfo {
+
+ /**
+ * 客户端标识
+ */
+ @ApiModelProperty(value = "客户端标识")
+ private String clientId;
+
+ /**
+ * 设备名称
+ */
+ @ApiModelProperty(value = "设备名称")
+ private String deviceName;
+ /**
+ * 连接实例
+ */
+ @ApiModelProperty(value = "连接实例")
+ private String connector;
+ /**
+ * 设备描述
+ */
+ @ApiModelProperty(value = "设备描述")
+ private String description;
+ /**
+ * 设备状态:1启用ENABLE || 2禁用DISABLE||未激活NOTACTIVE 0
+ */
+ @ApiModelProperty(value = "设备状态:1启用ENABLE || 2禁用DISABLE||未激活NOTACTIVE 0")
+ private Integer deviceStatus;
+ /**
+ * 连接状态:在线:1ONLINE || 离线:2OFFLINE || 未连接:INIT 0
+ */
+ @ApiModelProperty(value = "连接状态:在线:1ONLINE || 离线:2OFFLINE || 未连接:INIT 0")
+ private Integer connectStatus;
+ /**
+ * 设备标签
+ */
+ @ApiModelProperty(value = "设备标签")
+ private String deviceTags;
+ /**
+ * 产品标识
+ */
+ @ApiModelProperty(value = "产品标识")
+ private String productIdentification;
+ /**
+ * 软件版本
+ */
+ @ApiModelProperty(value = "软件版本")
+ private String swVersion;
+ /**
+ * 固件版本
+ */
+ @ApiModelProperty(value = "固件版本")
+ private String fwVersion;
+ /**
+ * sdk版本
+ */
+ @ApiModelProperty(value = "sdk版本")
+ private String deviceSdkVersion;
+ /**
+ * 网关设备id
+ */
+ @ApiModelProperty(value = "网关设备id")
+ private String gatewayId;
+ /**
+ * 设备类型:0普通设备 || 1网关设备 || 2子设备
+ */
+ @ApiModelProperty(value = "设备类型:0普通设备 || 1网关设备 || 2子设备 ")
+ private Integer nodeType;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+ }
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceFallbackFactory.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceFallbackFactory.java
index 62d6ffb2..ead39d30 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceFallbackFactory.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceFallbackFactory.java
@@ -3,6 +3,10 @@
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -62,14 +66,149 @@ public R findOneByClientId(String clientId) {
* @return
*/
@Override
- public R> selectAllByProductIdentification(String productIdentification){
+ public R> selectAllByProductIdentification(String productIdentification) {
return R.fail("查询产品下的设备:" + throwable.getMessage());
}
+
@Override
- public R> selectDeviceByDeviceIdentificationList(List deviceIdentificationList){
+ public R> selectDeviceByDeviceIdentificationList(List deviceIdentificationList) {
return R.fail("根据设备标识列表查询设备失败:" + throwable.getMessage());
}
+
+ /**
+ * (MQTT)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @Override
+ public R saveSubDeviceByMqtt(TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return R.fail("新增子设备失败:" + throwable.getMessage());
+ }
+
+ /**
+ * (HTTP)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @Override
+ public R saveSubDeviceByHttp(TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return R.fail("新增子设备失败:" + throwable.getMessage());
+ }
+
+ /**
+ * MQTT协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @Override
+ public R updateSubDeviceConnectStatusByMqtt(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ return R.fail("修改子设备连接状态失败:" + throwable.getMessage());
+ }
+
+ /**
+ * HTTP协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @Override
+ public R updateSubDeviceConnectStatusByHttp(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ return R.fail("修改子设备连接状态失败:" + throwable.getMessage());
+ }
+
+ /**
+ * MQTT协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @Override
+ public R deleteSubDeviceByMqtt(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ return R.fail("删除子设备失败:" + throwable.getMessage());
+ }
+
+ /**
+ * HTTP协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @Override
+ public R deleteSubDeviceByHttp(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ return R.fail("删除子设备失败:" + throwable.getMessage());
+ }
+
+ /**
+ * MQTT协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @Override
+ public R deviceDataReportByMqtt(TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ return R.fail("数据上报失败:" + throwable.getMessage());
+ }
+
+ /**
+ * HTTP协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @Override
+ public R deviceDataReportByHttp(TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ return R.fail("数据上报失败:" + throwable.getMessage());
+ }
+
+ /**
+ * Queries device information using the MQTT protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @Override
+ public R queryDeviceByMqtt(TopoQueryDeviceParam topoQueryDeviceParam) {
+ return R.fail("查询设备失败:" + throwable.getMessage());
+ }
+
+ /**
+ * Queries device information using the HTTP protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @Override
+ public R queryDeviceByHttp(TopoQueryDeviceParam topoQueryDeviceParam) {
+ return R.fail("查询设备失败:" + throwable.getMessage());
+ }
+
+ /**
+ * Receives and saves a new OTA upgrade record from an MQTT message. This endpoint
+ * captures the command response parameters from the MQTT message body and persists them.
+ *
+ * @param otaCommandResponseParam The response parameters from an OTA command sent via MQTT.
+ * @return {@link R} A response entity containing the saved OTA upgrade record.
+ */
+ @Override
+ public R saveUpgradeRecordByMqtt(OtaCommandResponseParam otaCommandResponseParam) {
+ return R.fail("保存升级记录失败:" + throwable.getMessage());
+ }
+
+ /**
+ * Receives and saves a new OTA upgrade record from an HTTP request. This endpoint
+ * captures the command response parameters from the request body and persists them.
+ *
+ * @param otaCommandResponseParam The response parameters from an OTA command sent via HTTP.
+ * @return {@link R} A response wrapper containing the saved OTA upgrade record.
+ */
+ @Override
+ public R saveUpgradeRecordByHttp(OtaCommandResponseParam otaCommandResponseParam) {
+ return R.fail("保存升级记录失败:" + throwable.getMessage());
+ }
};
}
}
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/SuperTableDescribeVO.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/SuperTableDescribeVO.java
new file mode 100644
index 00000000..7a05343e
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/SuperTableDescribeVO.java
@@ -0,0 +1,56 @@
+package com.mqttsnet.thinglinks.tdengine.api.domain;
+
+import cn.hutool.core.map.MapUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 超级表结构VO
+ * @packagename: com.mqttsnet.thinglinks.tds.vo.result
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-09-17 21:12
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "SuperTableDescribeVO", description = "超级表结构VO")
+public class SuperTableDescribeVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+ /**
+ * 标记
+ */
+ @ApiModelProperty(value = "标记")
+ private String note;
+ /**
+ * 字段名
+ */
+ @ApiModelProperty(value = "字段名")
+ private String field;
+ /**
+ * 字段长度
+ */
+ @ApiModelProperty(value = "字段长度")
+ private Integer length;
+ /**
+ * 字段类型
+ */
+ @ApiModelProperty(value = "字段类型")
+ private String type;
+
+
+}
diff --git a/thinglinks-common/pom.xml b/thinglinks-common/pom.xml
index a3a6c0b8..8203b209 100644
--- a/thinglinks-common/pom.xml
+++ b/thinglinks-common/pom.xml
@@ -20,6 +20,7 @@
thinglinks-common-job
thinglinks-common-kafka
thinglinks-common-seata
+ thinglinks-common-protocol
thinglinks-common
diff --git a/thinglinks-common/thinglinks-common-core/pom.xml b/thinglinks-common/thinglinks-common-core/pom.xml
index 21cda2c6..d92a38b4 100644
--- a/thinglinks-common/thinglinks-common-core/pom.xml
+++ b/thinglinks-common/thinglinks-common-core/pom.xml
@@ -118,7 +118,7 @@
cn.hutool
hutool-all
- 5.7.14
+ 5.8.26
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/CacheConstants.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/CacheConstants.java
index 1452ef39..12673b8a 100644
--- a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/CacheConstants.java
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/CacheConstants.java
@@ -2,19 +2,44 @@
/**
* redis缓存的key 常量
- *
+ *
* @author thinglinks
*/
-public class CacheConstants
-{
+public class CacheConstants {
/**
* 权限缓存前缀
*/
public final static String LOGIN_TOKEN_KEY = "login_tokens:";
+
+ /**
+ * 设备信息 cache key
+ * link-> device_record:deviceIdentification
+ */
+ public static final String DEVICE_RECORD_KEY = "device_record:";
+
+ /**
+ * 全局产品信息 前缀
+ * link-> def_product:productIdentification
+ */
+ public static final String PRODUCT = "def_product";
+
+ /**
+ * 全局产品模型 前缀
+ * link-> def_product_model:productIdentification
+ */
+ public static final String PRODUCT_MODEL = "def_product_model";
+
+ /**
+ * 全局产品模型超级表 前缀
+ * link-> def_product_model_super_table:productIdentification:serviceCode:deviceIdentification
+ */
+ public static final String PRODUCT_MODEL_SUPER_TABLE = "def_product_model_super_table";
+
/**
- * 产品初始化数据模型缓存前缀
+ * TDengine superTableFields cache key
+ * link-> tdengine_superTableFields:productIdentification:serviceCode:deviceIdentification
*/
- public final static String PRODUCT_INITIALIZEDATAMODEL = "product_initializeDataModel:";
+ public static final String TDENGINE_SUPERTABLEFILELDS = "tdengine_superTableFields:";
}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/Constants.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/Constants.java
index d36cb588..d42c11d4 100644
--- a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/Constants.java
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/Constants.java
@@ -141,24 +141,9 @@ public class Constants {
*/
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
- /**
- * 设备信息 cache key
- */
- public static final String DEVICE_RECORD_KEY = "device_record:";
-
/**
* 重复提交 cache key
*/
public static final String RESUBMIT_URL_KEY = "resubmit_url:";
- /**
- * TDengine superTableFields cache key
- */
- public static final String TDENGINE_SUPERTABLEFILELDS = "TDengine_SuperTableFields:";
-
- /**
- * 设备数据上报协议脚本 cache key
- */
- public static final String DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT = "device_data_reported_agreement_script:";
-
}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceConnectStatus.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceConnectStatus.java
deleted file mode 100644
index e598e906..00000000
--- a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceConnectStatus.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.mqttsnet.thinglinks.common.core.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * @Description: 连接状态
- * @Author: ShiHuan Sun
- * @E-mail: 13733918655@163.com
- * @CreateDate: 2021/10/25$ 15:54$
- * @UpdateUser: ShiHuan Sun
- * @UpdateDate: 2021/10/25$ 15:54$
- * @UpdateRemark: 修改内容
- * @Version: 1.0
- */
-@Getter
-@AllArgsConstructor
-public enum DeviceConnectStatus {
- /**
- * 初始化
- */
- INIT("INIT","INIT"),
-
- /**
- * 在线
- */
- ONLINE("ONLINE","ONLINE"),
-
- /**
- * 离线
- */
- OFFLINE("OFFLINE","OFFLINE");
-
- private String key;
- private String value;
-}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceConnectStatusEnum.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceConnectStatusEnum.java
new file mode 100644
index 00000000..86544aa3
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceConnectStatusEnum.java
@@ -0,0 +1,69 @@
+package com.mqttsnet.thinglinks.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * @Description: 连接状态
+ * @Author: ShiHuan Sun
+ * @E-mail: 13733918655@163.com
+ * @CreateDate: 2021/10/25$ 15:54$
+ * @UpdateUser: ShiHuan Sun
+ * @UpdateDate: 2021/10/25$ 15:54$
+ * @UpdateRemark: 修改内容
+ * @Version: 1.0
+ */
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+public enum DeviceConnectStatusEnum {
+ /**
+ * 初始化
+ */
+ INIT("INIT", "INIT"),
+
+ /**
+ * 在线
+ */
+ ONLINE("ONLINE", "ONLINE"),
+
+ /**
+ * 离线
+ */
+ OFFLINE("OFFLINE", "OFFLINE");
+
+ private String key;
+ private String value;
+
+ /**
+ * 根据key获取对应的枚举
+ *
+ * @param key 设备连接的状态值
+ * @return 返回对应的枚举,如果没找到则返回 Optional.empty()
+ */
+ public static Optional fromValue(String key) {
+ return Stream.of(DeviceConnectStatusEnum.values())
+ .filter(status -> status.getValue().equals(key))
+ .findFirst();
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerGroupConstant.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerGroupConstant.java
new file mode 100644
index 00000000..4d2e1155
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerGroupConstant.java
@@ -0,0 +1,19 @@
+package com.mqttsnet.thinglinks.common.core.mqs;
+
+/**
+ * @Description: 消费者组常量(队列)
+ * @Author: ShiHuan SUN
+ * @E-mail: 13733918655@163.com
+ * @Website: http://thinglinks.mqttsnet.com
+ * @CreateDate: 2022/4/15$ 15:53$
+ * @UpdateUser: ShiHuan SUN
+ * @UpdateDate: 2022/4/15$ 15:53$
+ * @UpdateRemark: 修改内容
+ * @Version: V1.0
+ */
+public interface ConsumerGroupConstant {
+ /**
+ * default-consumer-group
+ */
+ String THINGLINKS_GROUP = "thinglinks";
+}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerTopicConstant.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerTopicConstant.java
new file mode 100644
index 00000000..03907be1
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerTopicConstant.java
@@ -0,0 +1,102 @@
+package com.mqttsnet.thinglinks.common.core.mqs;
+
+/**
+ * @Description: 消费者主题常量(队列)
+ * @Author: ShiHuan SUN
+ * @E-mail: 13733918655@163.com
+ * @Website: http://thinglinks.mqttsnet.com
+ * @CreateDate: 2022/4/15$ 15:53$
+ * @UpdateUser: ShiHuan SUN
+ * @UpdateDate: 2022/4/15$ 15:53$
+ * @UpdateRemark: 修改内容
+ * @Version: V1.0
+ */
+public interface ConsumerTopicConstant {
+
+ /**
+ * MQTT Broker 监听主题
+ */
+ interface Mqtt {
+ /**
+ * MQTT设备消息监听主题——》MQTT消息——》MQS
+ */
+ String THINGLINKS_MQS_MQTT_MSG = "thinglinks-pro-mqs-mqttMsg";
+
+ /**
+ * 设备上线
+ */
+ String THINGLINKS_CLIENT_CONNECTED_TOPIC = "client.connected.topic";
+
+ /**
+ * 客户端设备离线
+ */
+ String THINGLINKS_CLIENT_DISCONNECTED_TOPIC = "client.disconnect.topic";
+
+ /**
+ * 服务端设备离线
+ */
+ String THINGLINKS_SERVER_CONNECTED_TOPIC = "server.disconnect.topic";
+
+ /**
+ * 设备离线
+ */
+ String THINGLINKS_DEVICE_KICKED_TOPIC = "device.kicked.topic";
+
+ /**
+ * 消息订阅
+ */
+ String THINGLINKS_SUBSCRIPTION_ACKED_TOPIC = "subscription.acked.topic";
+
+ /**
+ * 取消订阅
+ */
+ String THINGLINKS_UNSUBSCRIPTION_ACKED_TOPIC = "unsubscription.acked.topic";
+
+ /**
+ * 消息分发错误
+ */
+ String THINGLINKS_DISTRIBUTION_ERROR_TOPIC = "distribution.error.topic";
+
+ /**
+ * 消息分发
+ */
+ String THINGLINKS_DISTRIBUTION_COMPLETED_TOPIC = "distribution.completed.topic";
+
+
+ /**
+ * PING 请求
+ */
+ String THINGLINKS_PING_REQ_TOPIC = "ping.req.topic";
+
+ }
+
+ interface Link {
+
+ /**
+ * 产品服务
+ */
+ String THINGLINKS_PRO_PRODUCT_SERVICE_MSG = "thinglinks-pro-product-service-msg";
+
+ /**
+ * 产品服务属性
+ */
+ String THINGLINKS_PRO_PRODUCT_PROPERTY_MSG = "thinglinks-pro-product-property-msg";
+ }
+
+ interface Rule {
+
+ /**
+ * 规则引擎触发器规则动作监听主题
+ */
+ String THINGLINKS_RULE_TRIGGER = "thinglinks_rule_trigger";
+ }
+
+ interface Tdengine {
+
+ /**
+ * TDengine超级表创键修改动作监听主题
+ */
+ String PRODUCTSUPERTABLE_CREATEORUPDATE = "productSuperTable-createOrUpdate";
+ }
+
+}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/AesUtils.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/AesUtils.java
new file mode 100644
index 00000000..428c4075
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/AesUtils.java
@@ -0,0 +1,145 @@
+package com.mqttsnet.thinglinks.common.core.utils;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.SecureRandom;
+
+/**
+ * @Description: AES加密
+ * @Author: ShiHuan Sun
+ * @CreateDate: 2021/9/8$ 14:49$
+ * @UpdateUser: ShiHuan Sun
+ * @UpdateDate: 2021/9/8$ 14:49$
+ * @UpdateRemark: 修改内容
+ * @Version: 1.0
+ */
+public class AesUtils {
+ public static void main(String[] args) throws Exception {
+
+ String content = " {\n" +
+ " \"batID\": \"120434305152\",\n" +
+ " \"chgTime\": 293,\n" +
+ " \"detailsList\": [\n" +
+ " {\n" +
+ " \"elect\": 7.23,\n" +
+ " \"rateType\": 3,\n" +
+ " \"startTime\": \"2021-06-30 12:43:10\",\n" +
+ " \"stopTime\": \"2021-06-30 12:48:03\"\n" +
+ " }\n" +
+ " ],\n" +
+ " \"electAmount\": 1,\n" +
+ " \"equipNo\": \"1000280001000003\",\n" +
+ " \"flatElect\": 7.23,\n" +
+ " \"gunNo\": 0,\n" +
+ " \"orderSn\": \"100028000100000320210630124232\",\n" +
+ " \"peakElect\": 0,\n" +
+ " \"plateNo\": \"京888888\",\n" +
+ " \"rateModelID\": \"1\",\n" +
+ " \"sharpElect\": 0,\n" +
+ " \"startElect\": 41.1,\n" +
+ " \"startSoc\": 97,\n" +
+ " \"startTime\": \"2021-06-30 12:43:10\",\n" +
+ " \"stopElect\": 48.33,\n" +
+ " \"stopReason\": 53,\n" +
+ " \"stopSoc\": 100,\n" +
+ " \"stopTime\": \"2021-06-30 12:48:03\",\n" +
+ " \"swapSn\": \"100028000200000120210630120022\",\n" +
+ " \"valleyElect\": 0,\n" +
+ " \"vin\": \"LZ5RB7D37LB013286\"\n" +
+ " }";
+ System.out.println("加密内容:" + content);
+ String key = "FA171555405706F73D7B973DB89F0B47";
+ System.out.println("加密密钥和解密密钥:" + key);
+ String encrypt = aesEncrypt(content, key);
+ System.out.println("加密后:" +encrypt);
+ String decrypt = aesDecrypt(encrypt, key);
+ System.out.println("解密后:" + decrypt);
+ }
+ /**
+ * 编码
+ * @param bstr
+ * @return String
+ */
+ public static String Base64encode(byte[] bstr) {
+ return Base64.encodeBase64String(bstr);
+ }
+
+ /**
+ * 解码
+ * @param str
+ * @return string
+ */
+ public static byte[] Base64decode(String str) {
+ return Base64.decodeBase64(str);
+ }
+
+ /*
+ * AES加密
+ * @param content 待加密的内容
+ * @param encryptKey 加密密钥
+ * @return 加密后的byte[]
+ * @throws Exception
+ */
+ public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
+ KeyGenerator kgen = KeyGenerator.getInstance("AES");
+ /*防止linux下 随机生成key*/
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ random.setSeed(encryptKey.getBytes());
+ kgen.init(128, random);
+ Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
+
+ return cipher.doFinal(content.getBytes("UTF-8"));
+ }
+
+ /**
+ * AES加密为base 64 code
+ * @param content 待加密的内容
+ * @param encryptKey 加密密钥
+ * @return 加密后的base 64 code
+ * @throws Exception
+ */
+ public static String aesEncrypt(String content, String encryptKey) throws Exception {
+ return Base64encode(aesEncryptToBytes(content, encryptKey));
+ }
+
+ /**
+ * AES解密
+ * @param encryptBytes 待解密的byte[]
+ * @param decryptKey 解密密钥
+ * @return 解密后的String
+ * @throws Exception
+ */
+ public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) {
+ byte[] decryptBytes = new byte[0];
+ try {
+ KeyGenerator kgen = KeyGenerator.getInstance("AES");
+ /*防止linux下 随机生成key*/
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ random.setSeed(decryptKey.getBytes());
+ kgen.init(128, random);
+ Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+ cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
+ decryptBytes = cipher.doFinal(encryptBytes);
+ return new String(decryptBytes,"UTF-8");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return decryptKey;
+
+ }
+
+ /**
+ * 将base 64 code AES解密
+ * @param encryptStr 待解密的base 64 code
+ * @param decryptKey 解密密钥
+ * @return 解密后的string
+ * @throws Exception
+ */
+ public static String aesDecrypt(String encryptStr, String decryptKey){
+ return aesDecryptByBytes(Base64decode(encryptStr), decryptKey);
+ }
+}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/SHA256Utils.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/SHA256Utils.java
new file mode 100644
index 00000000..0cb1eae9
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/SHA256Utils.java
@@ -0,0 +1,67 @@
+package com.mqttsnet.thinglinks.common.core.utils;
+
+import org.springframework.stereotype.Component;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Random;
+
+@Component
+public class SHA256Utils {
+ public static void main(String[] args) {
+ String appId="123";
+ String appKey="123";
+ String timestamp="1568383635245";
+ String sha256String = getSHA256String(appId + appKey + timestamp);
+ System.out.println(sha256String);
+ }
+
+ /**
+ * 用java原生的摘要实现SHA256加密
+ *
+ * @param str 加密前的报文
+ * @return
+ */
+ public static String getSHA256String(String str) {
+ String encodeStr = "";
+ try {
+ MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
+ messageDigest.update(str.getBytes("UTF-8"));
+ encodeStr = byte2Hex(messageDigest.digest());
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return encodeStr;
+ }
+
+ /**
+ * byte[]转为16进制
+ *
+ * @param bytes
+ * @return
+ */
+ private static String byte2Hex(byte[] bytes) {
+ StringBuffer stringBuffer = new StringBuffer();
+ for (int i = 0; i < bytes.length; i++) {
+ String temp = Integer.toHexString(bytes[i] & 0xFF);
+ if (temp.length() == 1) {
+ stringBuffer.append("0");
+ }
+ stringBuffer.append(temp);
+ }
+ return stringBuffer.toString();
+ }
+
+ //随机密码 : 6位数字
+ public static String randompassword(){
+ char[] chars = new char[6];
+ Random rnd = new Random();
+ for(int i=0;i < 6 ; i++){
+ chars[i] = (char)('0'+rnd.nextInt(10));
+ }
+ return new String(chars);
+ }
+}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/Sm4Utils.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/Sm4Utils.java
new file mode 100644
index 00000000..b2108500
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/Sm4Utils.java
@@ -0,0 +1,101 @@
+package com.mqttsnet.thinglinks.common.core.utils;
+
+import org.bouncycastle.crypto.engines.SM4Engine;
+import org.bouncycastle.crypto.modes.CBCBlockCipher;
+import org.bouncycastle.crypto.paddings.PKCS7Padding;
+import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.util.encoders.Hex;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @Description: 国密SM4分组密码算法工具类(对称加密)
+ * @Author: ShiHuan Sun
+ * @CreateDate: 2021/8/25$ 15:27$
+ * @UpdateUser: ShiHuan Sun
+ * @UpdateDate: 2021/8/25$ 15:27$
+ * @UpdateRemark: 修改内容
+ * @Version: 1.0
+ */
+public class Sm4Utils {
+ /**
+ * 加密
+ *
+ * @param key 密钥
+ * @param iv 初始向量
+ * @param data 明文
+ * @return 密文
+ */
+ public static String encrypt(String key, String iv, String data) {
+ try {
+ // 创建SM4引擎
+ SM4Engine sm4Engine = new SM4Engine();
+ // 创建CBC模式的加密器
+ CBCBlockCipher cbcBlockCipher = new CBCBlockCipher(sm4Engine);
+ // 创建填充加密器
+ PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(cbcBlockCipher, new PKCS7Padding());
+ // 创建密钥参数
+ KeyParameter keyParameter = new KeyParameter(Hex.decode(key));
+ // 创建带IV的参数
+ ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, Hex.decode(iv));
+ // 初始化加密器
+ cipher.init(true, parametersWithIV);
+
+ byte[] encryptedData = new byte[cipher.getOutputSize(data.getBytes(StandardCharsets.UTF_8).length)];
+ int length = cipher.processBytes(data.getBytes(StandardCharsets.UTF_8), 0, data.getBytes(StandardCharsets.UTF_8).length, encryptedData, 0);
+ cipher.doFinal(encryptedData, length);
+
+ return Hex.toHexString(encryptedData);
+ } catch (Exception e) {
+ throw new RuntimeException("SM4加密失败", e);
+ }
+ }
+
+ /**
+ * 解密
+ *
+ * @param key 密钥
+ * @param iv 初始向量
+ * @param data 密文
+ * @return 明文
+ */
+ public static String decrypt(String key, String iv, String data) {
+ try {
+ // 创建SM4引擎
+ SM4Engine sm4Engine = new SM4Engine();
+ // 创建CBC模式的解密器
+ CBCBlockCipher cbcBlockCipher = new CBCBlockCipher(sm4Engine);
+ // 创建填充解密器
+ PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(cbcBlockCipher, new PKCS7Padding());
+ // 创建密钥参数
+ KeyParameter keyParameter = new KeyParameter(Hex.decode(key));
+ // 创建带IV的参数
+ ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, Hex.decode(iv));
+ // 初始化解密器
+ cipher.init(false, parametersWithIV);
+
+ byte[] decryptedData = new byte[cipher.getOutputSize(Hex.decode(data).length)];
+ int length = cipher.processBytes(Hex.decode(data), 0, Hex.decode(data).length, decryptedData, 0);
+ int finalLength = cipher.doFinal(decryptedData, length);
+
+ return new String(decryptedData, 0, length + finalLength, StandardCharsets.UTF_8);
+ } catch (Exception e) {
+ throw new RuntimeException("SM4解密失败", e);
+ }
+ }
+
+ public static void main(String[] args) {
+ String key = "0123456789abcdef0123456789abcdef";
+ String iv = "0123456789abcdef0123456789abcdef";
+ String data = "Hello, SM4!";
+
+ String encryptedData = Sm4Utils.encrypt(key, iv, data);
+ System.out.println("加密后的数据: " + encryptedData);
+
+ String decryptedData = Sm4Utils.decrypt(key, iv, encryptedData);
+ System.out.println("解密后的数据: " + decryptedData);
+ }
+
+}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/SnowflakeIdUtil.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/SnowflakeIdUtil.java
new file mode 100644
index 00000000..7eb1c04e
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/SnowflakeIdUtil.java
@@ -0,0 +1,143 @@
+package com.mqttsnet.thinglinks.common.core.utils;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * @program: thinglinks-util-pro
+ * @description: SnowflakeIdUtil 是一个基于雪花算法的唯一 ID 生成工具类。 雪花算法可以保证生成的 ID 全局唯一且趋势递增。
+ * @packagename: com.mqttsnet.basic.utils
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-03 13:15
+ **/
+public class SnowflakeIdUtil {
+
+ private static final SnowflakeIdUtil INSTANCE = new SnowflakeIdUtil();
+
+ // 开始时间戳 (2022-01-01)
+ private static final long START_TIMESTAMP = 1672444800000L;
+
+ // 工作器 ID 和数据中心 ID 的位数
+ private static final int WORKER_ID_BITS = 5;
+ private static final int DATACENTER_ID_BITS = 5;
+
+ // 序列号的位数
+ private static final int SEQUENCE_BITS = 12;
+
+ // 工作器 ID 和数据中心 ID 的最大值
+ private static final int MAX_WORKER_ID = ~(-1 << WORKER_ID_BITS);
+ private static final int MAX_DATACENTER_ID = ~(-1 << DATACENTER_ID_BITS);
+
+ // 工作器 ID、数据中心 ID 和序列号的位移
+ private static final int WORKER_ID_SHIFT = SEQUENCE_BITS;
+ private static final int DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
+ private static final int TIMESTAMP_SHIFT = DATACENTER_ID_SHIFT + DATACENTER_ID_BITS;
+
+ // 序列号的掩码
+ private static final int SEQUENCE_MASK = ~(-1 << SEQUENCE_BITS);
+
+ // 工作器 ID 和数据中心 ID
+ private final int workerId;
+ private final int datacenterId;
+
+ // 序列号和上次生成 ID 的时间戳
+ private int sequence = 0;
+ private long lastTimestamp = -1L;
+
+ /**
+ * 创建一个新的 SnowflakeIdUtil 实例。
+ */
+ public SnowflakeIdUtil() {
+ this.workerId = generateWorkerId();
+ this.datacenterId = generateDatacenterId();
+ }
+
+
+ /**
+ * 生成一个新的唯一 ID,默认为 16 位。
+ *
+ * @return 一个不重复的十进制字符串
+ */
+ public static String nextId() {
+ return INSTANCE.nextId(16);
+ }
+
+ /**
+ * 生成一个新的唯一 ID。
+ *
+ * @param numDigits 生成的 ID 的位数,最少为 16 位
+ * @return 一个不重复的十进制字符串
+ */
+ public synchronized String nextId(int numDigits) {
+ if (numDigits < 16) {
+ throw new IllegalArgumentException("numDigits must be at least 16");
+ }
+
+ long id = nextLongId();
+ String idString = String.format("%0" + numDigits + "d", id % (long) Math.pow(10, numDigits));
+ return idString;
+ }
+
+ /**
+ * 生成一个新的唯一长整型 ID。
+ *
+ * @return 一个不重复的长整型值
+ */
+ public synchronized long nextLongId() {
+ long timestamp = System.currentTimeMillis();
+
+ if (timestamp < lastTimestamp) {
+ throw new RuntimeException("Clock moved backwards. Refusing to generate id.");
+ }
+
+ if (timestamp == lastTimestamp) {
+ sequence = (sequence + 1) & SEQUENCE_MASK;
+ if (sequence == 0) {
+ timestamp = waitUntilNextMillis(lastTimestamp);
+ }
+ } else {
+ sequence = 0;
+ }
+
+ lastTimestamp = timestamp;
+
+ long id = ((timestamp - START_TIMESTAMP) << TIMESTAMP_SHIFT)
+ | (datacenterId << DATACENTER_ID_SHIFT)
+ | (workerId << WORKER_ID_SHIFT)
+ | sequence;
+
+ return id;
+ }
+
+ /**
+ * 等待直到下一个毫秒。
+ *
+ * @param lastTimestamp 上次生成 ID 的时间戳
+ * @return 当前时间戳
+ */
+ private long waitUntilNextMillis(long lastTimestamp) {
+ long timestamp = System.currentTimeMillis();
+ while (timestamp <= lastTimestamp) {
+ timestamp = System.currentTimeMillis();
+ }
+ return timestamp;
+ }
+
+ /**
+ * 生成工作器 ID。
+ *
+ * @return 一个介于 0 和最大工作器 ID 之间的整数
+ */
+ private int generateWorkerId() {
+ return ThreadLocalRandom.current().nextInt(MAX_WORKER_ID + 1);
+ }
+
+ /**
+ * 生成数据中心 ID。
+ *
+ * @return 一个介于 0 和最大数据中心 ID 之间的整数
+ */
+ private int generateDatacenterId() {
+ return ThreadLocalRandom.current().nextInt(MAX_DATACENTER_ID + 1);
+ }
+}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/bean/BeanPlusUtil.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/bean/BeanPlusUtil.java
new file mode 100755
index 00000000..2800b0e4
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/utils/bean/BeanPlusUtil.java
@@ -0,0 +1,40 @@
+package com.mqttsnet.thinglinks.common.core.utils.bean;
+
+import cn.hutool.core.bean.BeanUtil;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Bean增强类工具类
+ *
+ *
+ * 把一个拥有对属性进行set和get方法的类,我们就可以称之为JavaBean。
+ *
+ *
+ * @author mqttsnet
+ * @since 3.1.2
+ */
+public class BeanPlusUtil extends BeanUtil {
+
+ /**
+ * 转换 list
+ *
+ * @param sourceList 源集合
+ * @param destinationClass 目标类型
+ * @return 目标集合
+ */
+ public static List toBeanList(Collection sourceList, Class destinationClass) {
+ if (sourceList == null || sourceList.isEmpty() || destinationClass == null) {
+ return Collections.emptyList();
+ }
+ return sourceList.parallelStream()
+ .filter(Objects::nonNull)
+ .map(source -> toBean(source, destinationClass))
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/constant/ConsumerTopicConstant.java b/thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/constant/ConsumerTopicConstant.java
deleted file mode 100644
index 47923bf6..00000000
--- a/thinglinks-common/thinglinks-common-kafka/src/main/java/com/mqttsnet/thinglinks/common/kafka/constant/ConsumerTopicConstant.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.mqttsnet.thinglinks.common.kafka.constant;
-
-import lombok.Data;
-
-/**
- * @Description: 消费者主题常量
- * @Author: ShiHuan SUN
- * @E-mail: 13733918655@163.com
- * @Website: http://thinglinks.mqttsnet.com
- * @CreateDate: 2022/4/15$ 15:53$
- * @UpdateUser: ShiHuan SUN
- * @UpdateDate: 2022/4/15$ 15:53$
- * @UpdateRemark: 修改内容
- * @Version: V1.0
- */
-@Data
-public class ConsumerTopicConstant {
-
- /**
- * SMQTT设备消息监听主题
- */
- public static final String THINGLINKS_LINK_MQTT_MSG = "thinglinks-link-mqttMsg";
-
- /**
- * TDengine超级表创键修改动作监听主题
- */
- public static final String PRODUCTSUPERTABLE_CREATEORUPDATE = "productSuperTable-createOrUpdate";
-
- /**
- * 系统指标数据采集动作监听主题
- */
- public static final String THINGLINKS_COLLECTION_SYSTEM = "thinglinks_collection_system";
-
- /**
- * 规则引擎触发器规则动作监听主题
- */
- public static final String THINGLINKS_RULE_TRIGGER = "thinglinks_rule_trigger";
-
- /**
- * 设备上线
- */
- public static final String THINGLINKS_CLIENT_CONNECTED_TOPIC = "client.connected.topic";
-
- /**
- * 客户端设备离线
- */
- public static final String THINGLINKS_CLIENT_DISCONNECTED_TOPIC = "client.disconnect.topic";
-
- /**
- * 服务端设备离线
- */
- public static final String THINGLINKS_SERVER_CONNECTED_TOPIC = "server.disconnect.topic";
-
- /**
- * 设备离线
- */
- public static final String THINGLINKS_DEVICE_KICKED_TOPIC = "device.kicked.topic";
-
- /**
- * 消息订阅
- */
- public static final String THINGLINKS_SUBSCRIPTION_ACKED_TOPIC = "subscription.acked.topic";
-
- /**
- * 取消订阅
- */
- public static final String THINGLINKS_UNSUBSCRIPTION_ACKED_TOPIC = "unsubscription.acked.topic";
-
- /**
- * 消息分发错误
- */
- public static final String THINGLINKS_DISTRIBUTION_ERROR_TOPIC = "distribution.error.topic";
-
- /**
- * 消息分发
- */
- public static final String THINGLINKS_DISTRIBUTION_COMPLETED_TOPIC = "distribution.completed.topic";
-
-
-
-
-}
diff --git a/thinglinks-common/thinglinks-common-protocol/README.md b/thinglinks-common/thinglinks-common-protocol/README.md
new file mode 100644
index 00000000..7d5cb942
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-protocol/README.md
@@ -0,0 +1,4 @@
+# 说明
+本模块用于协议底层处理
+
+
diff --git a/thinglinks-common/thinglinks-common-protocol/pom.xml b/thinglinks-common/thinglinks-common-protocol/pom.xml
new file mode 100644
index 00000000..26c2e327
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-protocol/pom.xml
@@ -0,0 +1,24 @@
+
+
+
+ com.mqttsnet
+ thinglinks-common
+ ${thinglinks.version}
+
+
+ 4.0.0
+ thinglinks-common-protocol
+ ${project.artifactId}
+ 协议解析核心服务模块
+
+
+
+
+ com.mqttsnet
+ thinglinks-common-core
+ ${thinglinks.version}
+
+
+
\ No newline at end of file
diff --git a/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/factory/ProtocolMessageAdapter.java b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/factory/ProtocolMessageAdapter.java
new file mode 100644
index 00000000..1a5ab6c9
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/factory/ProtocolMessageAdapter.java
@@ -0,0 +1,76 @@
+package com.mqttsnet.basic.protocol.factory;
+
+import java.util.Map;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.basic.protocol.model.ProtocolDataMessageDTO;
+import com.mqttsnet.basic.protocol.utils.ProtocolMessageSignatureVerifierUtils;
+import com.mqttsnet.basic.protocol.utils.ProtocolRegexTopicVariableExtractorUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 协议信息适配器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-30 15:08
+ **/
+@Slf4j
+@Component
+public class ProtocolMessageAdapter {
+
+ public boolean validateProtocolData(String body) {
+ return ProtocolMessageSignatureVerifierUtils.validateProtocolData(body);
+ }
+
+ public Map extractVariables(String topic) {
+ return ProtocolRegexTopicVariableExtractorUtils.extractVariables(topic);
+ }
+
+ public ProtocolDataMessageDTO parseProtocolDataMessage(String body) {
+ return BeanUtil.toBean(JSON.parseObject(body), ProtocolDataMessageDTO.class);
+ }
+
+ public String decryptMessage(String body, EncryptionDetailsDTO encryptionDetailsDTO) throws Exception {
+ String signKey = encryptionDetailsDTO.getSignKey();
+ String encryptKey = encryptionDetailsDTO.getEncryptKey();
+ String encryptVector = encryptionDetailsDTO.getEncryptVector();
+ return ProtocolMessageSignatureVerifierUtils.decryptMessage(body, signKey, encryptKey, encryptVector);
+ }
+
+ public ProtocolDataMessageDTO buildResponse(ProtocolDataMessageDTO protocolDataMessageDTO,
+ String resultDataBody, EncryptionDetailsDTO encryptionDetailsDTO) throws Exception {
+ String signKey = encryptionDetailsDTO.getSignKey();
+ String encryptKey = encryptionDetailsDTO.getEncryptKey();
+ String encryptVector = encryptionDetailsDTO.getEncryptVector();
+ //数据加密签名处理
+ String dataBody = ProtocolMessageSignatureVerifierUtils.encryptMessage(resultDataBody, protocolDataMessageDTO.getHead().getCipherFlag(), signKey, encryptKey,
+ encryptVector);
+ //JSON字符串转换为对象
+ protocolDataMessageDTO = JSON.parseObject(dataBody, new TypeReference() {
+ });
+
+
+ return protocolDataMessageDTO;
+ }
+
+ public ProtocolDataMessageDTO buildResponse(String resultDataBody, EncryptionDetailsDTO encryptionDetailsDTO) throws Exception {
+ String signKey = encryptionDetailsDTO.getSignKey();
+ String encryptKey = encryptionDetailsDTO.getEncryptKey();
+ String encryptVector = encryptionDetailsDTO.getEncryptVector();
+ //数据加密签名处理
+ String dataBody = ProtocolMessageSignatureVerifierUtils.encryptMessage(resultDataBody, encryptionDetailsDTO.getCipherFlag(), signKey, encryptKey,
+ encryptVector);
+ //JSON字符串转换为对象
+ ProtocolDataMessageDTO protocolDataMessageDTO = JSON.parseObject(dataBody, new TypeReference() {
+ });
+
+
+ return protocolDataMessageDTO;
+ }
+}
diff --git a/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/model/EncryptionDetailsDTO.java b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/model/EncryptionDetailsDTO.java
new file mode 100644
index 00000000..3dc3f685
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/model/EncryptionDetailsDTO.java
@@ -0,0 +1,69 @@
+package com.mqttsnet.basic.protocol.model;
+
+import java.io.Serializable;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: EncryptionDetailsDto.java
+ * -----------------------------------------------------------------------------
+ * Description:
+ * This class is used to encapsulate encryption and decryption details , for message processing, providing necessary information without
+ * -----------------------------------------------------------------------------
+ *
+ * @author ShiHuan Sun
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ *
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023-11-12 01:48
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
+public class EncryptionDetailsDTO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+
+ /**
+ * The key used for signing the data. This is usually a secret key
+ * shared between the sender and the receiver to verify the integrity
+ * of the message.
+ */
+ private String signKey;
+
+ /**
+ * The key used for encrypting the data. This is typically a symmetric key
+ * used in encryption algorithms to ensure that the message contents are
+ * not readable by unauthorized parties.
+ */
+ private String encryptKey;
+
+ /**
+ * The initialization vector (IV) used for encryption algorithms that require it.
+ * The IV is a pseudo-random value and is used to ensure that the encryption
+ * result is different for the same plaintext and key.
+ */
+ private String encryptVector;
+
+ /**
+ * Indicates the encryption method used. Different values represent different
+ * encryption algorithms or no encryption.
+ * For example, 0 might represent no encryption, 1 might represent AES, etc.
+ */
+ private Integer cipherFlag;
+}
diff --git a/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/model/ProtocolDataMessageDTO.java b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/model/ProtocolDataMessageDTO.java
new file mode 100644
index 00000000..23c4c2ac
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/model/ProtocolDataMessageDTO.java
@@ -0,0 +1,68 @@
+package com.mqttsnet.basic.protocol.model;
+
+import java.io.Serializable;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: ProtocolDataMessageDto.java
+ * -----------------------------------------------------------------------------
+ * Description:
+ * ProtocolDataMessage
+ * -----------------------------------------------------------------------------
+ *
+ * @author ShiHuan Sun
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ *
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023-11-12 01:50
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@Builder
+@ApiModel(value = "ProtocolDataMessageDto", description = "协议数据内容Dto")
+public class ProtocolDataMessageDTO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "消息头部")
+ private Head head;
+
+ @ApiModelProperty(value = "报文体")
+ private T dataBody;
+
+ @ApiModelProperty(value = "数据签名")
+ private String dataSign;
+
+ @ApiModel(description = "消息头部实体类")
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Builder
+ public static class Head {
+ @ApiModelProperty(value = "加密标志,0-不加密;1-SM4;2-AES", allowableValues = "0, 1, 2", example = "0")
+ private Integer cipherFlag;
+
+ @ApiModelProperty(value = "消息ID(从1自增即可)", example = "3342")
+ private Long mid;
+
+ @ApiModelProperty(value = "报文发送时间戳(毫秒)", example = "1624982406963")
+ private Long timeStamp;
+ }
+}
diff --git a/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/utils/ProtocolMessageSignatureVerifierUtils.java b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/utils/ProtocolMessageSignatureVerifierUtils.java
new file mode 100644
index 00000000..f0b729ec
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/utils/ProtocolMessageSignatureVerifierUtils.java
@@ -0,0 +1,285 @@
+package com.mqttsnet.basic.protocol.utils;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mqttsnet.thinglinks.common.core.utils.AesUtils;
+import com.mqttsnet.thinglinks.common.core.utils.Sm4Utils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.digest.DigestUtils;
+
+/**
+ * @program: thinglinks-util-pro
+ * @description: 协议消息处理Utils
+ * @packagename: com.mqttsnet.basic.utils
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-07 00:12
+ **/
+@Slf4j
+public class ProtocolMessageSignatureVerifierUtils {
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ /**
+ * 加密报文体
+ *
+ * @param dataBody 报文体
+ * @param cipherFlag 加密标识 0:不加密 1:SM4加密 2:AES加密
+ * @param signKey 数据签名密钥
+ * @param encryptKey 加密密钥
+ * @param encryptVector 加密向量
+ * @return 加密后的报文体
+ * @throws IOException
+ */
+ public static String encryptMessage(String dataBody, int cipherFlag, String signKey, String encryptKey, String encryptVector) throws Exception {
+ // 加密报文体
+ String encryptedDataBody = encryptDataBody(dataBody, cipherFlag, encryptKey, encryptVector);
+
+ // 计算数据签名
+ long timeStamp = System.currentTimeMillis();
+ String dataSign = calculateDataSign(dataBody, timeStamp, signKey);
+
+ // 构建加密后的报文
+ Map head = new HashMap<>();
+ head.put("cipherFlag", cipherFlag);
+ head.put("timeStamp", timeStamp);
+
+ Map encryptedMessage = new HashMap<>();
+ encryptedMessage.put("head", head);
+ encryptedMessage.put("dataBody", objectMapper.readValue(encryptedDataBody, Object.class));
+ encryptedMessage.put("dataSign", dataSign);
+
+ // 转换为 JSON 字符串
+ return objectMapper.writeValueAsString(encryptedMessage);
+ }
+
+ /**
+ * 解密报文体
+ *
+ * @param messageJson 加密后的报文
+ * @param signKey 数据签名密钥
+ * @param encryptKey 加密密钥
+ * @param encryptVector 加密向量
+ * @return 解密后的报文体
+ * @throws IOException
+ */
+ public static String decryptMessage(String messageJson, String signKey, String encryptKey, String encryptVector) throws Exception {
+ // 解析 JSON 报文
+ Map message = objectMapper.readValue(messageJson, HashMap.class);
+
+ // 获取报文头部信息
+ Map head = (Map) message.get("head");
+ int cipherFlag = (int) head.get("cipherFlag");
+ long timeStamp = (long) head.get("timeStamp");
+
+ // 获取加密后的报文体和数据签名
+ String encryptedDataBody = objectMapper.writeValueAsString(message.get("dataBody"));
+ String dataSign = (String) message.get("dataSign");
+
+ // 验证数据签名
+ if (CharSequenceUtil.isNotBlank(dataSign) && !verifyDataSign(encryptedDataBody, timeStamp, signKey, dataSign)) {
+ throw new IllegalArgumentException("Invalid data sign");
+ }
+
+ // 解密报文体
+ return decryptDataBody(encryptedDataBody, cipherFlag, encryptKey, encryptVector);
+
+ }
+
+ private static String encryptDataBody(String dataBody, int cipherFlag, String encryptKey, String encryptVector) throws Exception {
+ // 根据 cipherFlag 实现加密逻辑
+ switch (cipherFlag) {
+ case 0:
+ return dataBody;
+ case 1:
+ // 使用 SM4 加密算法
+ return sm4Encrypt(dataBody, encryptKey, encryptVector);
+ case 2:
+ // 使用 AES 加密算法
+ return aesEncrypt(dataBody, encryptKey, encryptVector);
+ default:
+ // 不加密
+ return dataBody;
+ }
+ }
+
+
+ private static String decryptDataBody(String encryptedDataBody, int cipherFlag, String encryptKey, String encryptVector) throws Exception {
+ // 根据 cipherFlag 实现解密逻辑
+ switch (cipherFlag) {
+ case 0:
+ return encryptedDataBody;
+ case 1:
+ // 使用 SM4 解密算法
+ return sm4Decrypt(encryptedDataBody, encryptKey, encryptVector);
+ case 2:
+ // 使用 AES 解密算法
+ return aesDecrypt(encryptedDataBody, encryptKey, encryptVector);
+ default:
+ // 不解密
+ return encryptedDataBody;
+ }
+ }
+
+ /**
+ * 使用 SM4 加密算法加密数据
+ *
+ * @param data 原始数据
+ * @param encryptKey 加密密钥
+ * @param encryptVector 加密向量
+ * @return 加密后的数据
+ */
+ private static String sm4Encrypt(String data, String encryptKey, String encryptVector) throws Exception {
+ return Sm4Utils.encrypt(encryptKey, encryptVector, data);
+ }
+
+ /**
+ * 使用 SM4 解密算法解密数据
+ *
+ * @param encryptedData 加密后的数据
+ * @param encryptKey 加密密钥
+ * @param encryptVector 加密向量
+ * @return 解密后的数据
+ */
+ private static String sm4Decrypt(String encryptedData, String encryptKey, String encryptVector) throws Exception {
+ return Sm4Utils.decrypt(encryptKey, encryptVector, encryptedData);
+ }
+
+ /**
+ * 使用 AES 加密算法加密数据
+ *
+ * @param data 原始数据
+ * @param encryptKey 加密密钥
+ * @param encryptVector 加密向量
+ * @return 加密后的数据
+ */
+ private static String aesEncrypt(String data, String encryptKey, String encryptVector) throws Exception {
+ String encrypt = AesUtils.aesEncrypt(data, encryptKey);
+ log.info("AES,加密输出HEX = %s \n" + encrypt);
+ return encrypt;
+ }
+
+ /**
+ * 使用 AES 解密算法解密数据
+ *
+ * @param encryptedData 加密后的数据
+ * @param encryptKey 加密密钥
+ * @param encryptVector 加密向量
+ * @return 解密后的数据
+ */
+ private static String aesDecrypt(String encryptedData, String encryptKey, String encryptVector) {
+ String decrypt = AesUtils.aesDecrypt(encryptedData, encryptKey);
+ log.info("AES,解密输出HEX = %s \n" + decrypt);
+ return decrypt;
+ }
+
+ /**
+ * 计算数据签名 (SHA256)
+ *
+ * @param dataBody 报文体
+ * @param timeStamp 时间戳
+ * @param signKey 签名密钥
+ * @return 数据签名
+ */
+ private static String calculateDataSign(String dataBody, long timeStamp, String signKey) {
+ // 使用 dataBody、timeStamp 和 signKey 计算签名
+ return generateDataSign(dataBody, timeStamp, signKey);
+ }
+
+ /**
+ * 生成数据签名
+ *
+ * @param dataBody 报文体
+ * @param timeStamp 时间戳
+ * @param signKey 签名密钥
+ * @return 数据签名
+ */
+ public static String generateDataSign(String dataBody, long timeStamp, String signKey) {
+ String dataToSign = dataBody + ":" + timeStamp + ":" + signKey;
+ return DigestUtils.md5Hex(dataToSign);
+ }
+
+ /**
+ * 验证协议内容是否合法(系统默认数据格式)
+ *
+ * @param jsonString
+ * @return true:合法,false:不合法
+ */
+ public static boolean validateProtocolData(String jsonString) {
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ JsonNode rootNode = objectMapper.readTree(jsonString);
+
+ // 校验一级字段
+ if (!validateJsonNode(rootNode, "head", JsonNode::isObject) ||
+ !validateJsonNode(rootNode, "dataBody", JsonNode::isObject) ||
+ !validateJsonNode(rootNode, "dataSign", JsonNode::isTextual)) {
+ return false;
+ }
+
+ JsonNode headNode = rootNode.get("head");
+
+ // 校验二级字段和字段类型
+ /*if (!validateJsonNode(headNode, "mid", JsonNode::isLong) ||
+ !validateJsonNode(headNode, "cipherFlag", JsonNode::isInt) ||
+ !validateJsonNode(headNode, "timeStamp", JsonNode::isLong)) {
+ return false;
+ }*/
+
+ // 校验必传字段
+ if (headNode.get("mid").asLong() <= 0 || headNode.get("timeStamp").asLong() <= 0) {
+ return false;
+ }
+
+ // 校验加密标志范围
+ int cipherFlag = headNode.get("cipherFlag").asInt();
+ if (cipherFlag < 0 || cipherFlag > 2) {
+ return false;
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ return true;
+ }
+
+ private static boolean validateJsonNode(JsonNode node, String fieldName, Function validator) {
+ return node.has(fieldName) && validator.apply(node.get(fieldName));
+ }
+
+
+ private static boolean verifyDataSign(String decryptedDataBody, long timeStamp, String signKey, String dataSign) {
+ // 使用 decryptedDataBody、timeStamp 和 signKey 计算签名
+ String calculatedSign = calculateDataSign(decryptedDataBody, timeStamp, signKey);
+
+ // 比较计算出的签名和报文中的签名
+ return calculatedSign.equals(dataSign);
+ }
+
+ public static void main(String[] args) {
+ String dataBody = "12233";
+ int cipherFlag = 2;
+ String signKey = "yousignkey";
+ String encryptKey = "yourncryptey";
+ String encryptVector = "yourncryptvector";
+
+ try {
+ // 加密报文
+ String encryptedMessage = encryptMessage(dataBody, cipherFlag, signKey, encryptKey, encryptVector);
+ System.out.println("Encrypted message: " + encryptedMessage);
+
+ // 解密报文
+ String decryptedDataBody = decryptMessage(encryptedMessage, signKey, encryptKey, encryptVector);
+ System.out.println("Decrypted data body: " + decryptedDataBody);
+ } catch (Exception e) {
+ System.err.println("Error processing message: " + e.getMessage());
+ }
+ }
+}
diff --git a/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/utils/ProtocolRegexTopicVariableExtractorUtils.java b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/utils/ProtocolRegexTopicVariableExtractorUtils.java
new file mode 100644
index 00000000..1c2e4284
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/utils/ProtocolRegexTopicVariableExtractorUtils.java
@@ -0,0 +1,47 @@
+package com.mqttsnet.basic.protocol.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @program: thinglinks-util-pro
+ * @description: 协议Topic变量提取工具类
+ * RegexVariableExtractor is a utility class that provides methods to extract
+ * specific variables (version and deviceId) from a given input string.
+ * @packagename: com.mqttsnet.basic.utils.protocol
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-07 14:10
+ **/
+public class ProtocolRegexTopicVariableExtractorUtils {
+
+ /**
+ * Extracts the version and deviceId variables from the given input string.
+ *
+ * @param input The input string to extract the variables from.
+ * @return A Map containing the extracted version and deviceId variables.
+ */
+ public static Map extractVariables(String input) {
+ // Define the regex pattern to match the version and deviceId variables
+ String pattern = "/([^/]+)/devices/([^/]+)";
+
+ // Compile the regex pattern
+ Pattern compiledPattern = Pattern.compile(pattern);
+ // Match the input string against the compiled pattern
+ Matcher matcher = compiledPattern.matcher(input);
+
+ // Create a map to store the extracted variables
+ Map variables = new HashMap<>();
+
+ // If the input string matches the pattern, extract the version and deviceId variables
+ if (matcher.find()) {
+ variables.put("version", matcher.group(1));
+ variables.put("deviceId", matcher.group(2));
+ }
+
+ // Return the map containing the extracted variables
+ return variables;
+ }
+}
diff --git a/thinglinks-common/thinglinks-common-protocol/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/thinglinks-common/thinglinks-common-protocol/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 00000000..a311a045
--- /dev/null
+++ b/thinglinks-common/thinglinks-common-protocol/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter
\ No newline at end of file
diff --git a/thinglinks-common/thinglinks-common-rocketmq/src/main/java/com/mqttsnet/thinglinks/common/rocketmq/constant/ConsumerGroupConstant.java b/thinglinks-common/thinglinks-common-rocketmq/src/main/java/com/mqttsnet/thinglinks/common/rocketmq/constant/ConsumerGroupConstant.java
deleted file mode 100644
index 653fbfee..00000000
--- a/thinglinks-common/thinglinks-common-rocketmq/src/main/java/com/mqttsnet/thinglinks/common/rocketmq/constant/ConsumerGroupConstant.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.mqttsnet.thinglinks.common.rocketmq.constant;
-
-/**
- * @Description: 消费者组常量
- * @Author: ShiHuan SUN
- * @E-mail: 13733918655@163.com
- * @Website: http://thinglinks.mqttsnet.com
- * @CreateDate: 2022/4/15$ 15:53$
- * @UpdateUser: ShiHuan SUN
- * @UpdateDate: 2022/4/15$ 15:53$
- * @UpdateRemark: 修改内容
- * @Version: V1.0
- */
-public class ConsumerGroupConstant {
-
- /**
- * broker-consumer-group
- */
- public static final String THINGLINKS_BROKER_GROUP = "thinglinks-broker";
-
- /**
- * link-consumer-group
- */
- public static final String THINGLINKS_LINK_GROUP = "thinglinks-link";
-
- /**
- * tdengine-consumer-group
- */
- public static final String THINGLINKS_TDENGINE_GROUP = "thinglinks-tdengine";
-
- /**
- * job-consumer-group
- */
- public static final String THINGLINKS_JOB_GROUP = "thinglinks-job";
-
- /**
- * rule-consumer-group
- */
- public static final String THINGLINKS_RULE_GROUP = "thinglinks-rule";
-
-
-}
diff --git a/thinglinks-common/thinglinks-common-rocketmq/src/main/java/com/mqttsnet/thinglinks/common/rocketmq/constant/ConsumerTopicConstant.java b/thinglinks-common/thinglinks-common-rocketmq/src/main/java/com/mqttsnet/thinglinks/common/rocketmq/constant/ConsumerTopicConstant.java
deleted file mode 100644
index bef68340..00000000
--- a/thinglinks-common/thinglinks-common-rocketmq/src/main/java/com/mqttsnet/thinglinks/common/rocketmq/constant/ConsumerTopicConstant.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.mqttsnet.thinglinks.common.rocketmq.constant;
-
-import lombok.Data;
-
-/**
- * @Description: 消费者主题常量
- * @Author: ShiHuan SUN
- * @E-mail: 13733918655@163.com
- * @Website: http://thinglinks.mqttsnet.com
- * @CreateDate: 2022/4/15$ 15:53$
- * @UpdateUser: ShiHuan SUN
- * @UpdateDate: 2022/4/15$ 15:53$
- * @UpdateRemark: 修改内容
- * @Version: V1.0
- */
-@Data
-public class ConsumerTopicConstant {
-
- /**
- * MQTT设备消息监听主题
- */
- public static final String THINGLINKS_LINK_MQTT_MSG = "thinglinks-link-mqttMsg";
-
- /**
- * TDengine超级表创键修改动作监听主题
- */
- public static final String PRODUCTSUPERTABLE_CREATEORUPDATE = "productSuperTable-createOrUpdate";
-
- /**
- * 系统指标数据采集动作监听主题
- */
- public static final String THINGLINKS_COLLECTION_SYSTEM = "thinglinks_collection_system";
-
- /**
- * 规则引擎触发器规则动作监听主题
- */
- public static final String THINGLINKS_RULE_TRIGGER = "thinglinks_rule_trigger";
-
-}
diff --git a/thinglinks-modules/thinglinks-modules-broker/pom.xml b/thinglinks-modules/thinglinks-modules-broker/pom.xml
index 6dac3ed0..cb237e9f 100644
--- a/thinglinks-modules/thinglinks-modules-broker/pom.xml
+++ b/thinglinks-modules/thinglinks-modules-broker/pom.xml
@@ -61,6 +61,20 @@
${thinglinks.version}
+
+
+ com.mqttsnet
+ thinglinks-common-kafka
+ ${thinglinks.version}
+
+
+
+
+ com.mqttsnet
+ thinglinks-common-protocol
+ ${thinglinks.version}
+
+
com.mqttsnet
@@ -79,6 +93,13 @@
${thinglinks.version}
+
+ com.mqttsnet
+ thinglinks-modules-link
+ ${thinglinks.version}
+
+
+
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/common/asyncthread/BrokerAsyncConfig.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/common/asyncthread/BrokerAsyncConfig.java
new file mode 100644
index 00000000..30a9848d
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/common/asyncthread/BrokerAsyncConfig.java
@@ -0,0 +1,94 @@
+package com.mqttsnet.thinglinks.broker.common.asyncthread;
+
+import com.mqttsnet.thinglinks.common.core.asyncthread.SuRejectHandle;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+/**
+ * 异步@Async多线程配置
+ * 使用原则:每一个业务场景使用独立的线程池,不要使用全局共享线程池
+ *
+ * @author thinglinks
+ */
+@Configuration
+@EnableAsync
+public class BrokerAsyncConfig {
+
+ /**
+ * 核心线程数(默认线程数)
+ */
+ @Value("${threadBus.pool.core-pool-size}")
+ private int corePoolSize = Runtime.getRuntime().availableProcessors();
+ /**
+ * 最大线程数
+ */
+ @Value("${threadBus.pool.max-pool-size}")
+ private int maxPoolSize = Runtime.getRuntime().availableProcessors();
+ /**
+ * 允许线程空闲时间(单位:默认为秒)
+ */
+ @Value("${threadBus.pool.keep-alive-time}")
+ private int keepAliveTime = 60;
+ /**
+ * 缓冲队列大小
+ */
+ @Value("${threadBus.pool.queue-capacity}")
+ private int queueCapacity = 200;
+ /**
+ * 线程池名前缀
+ */
+ @Value("${threadBus.pool.thread-name-prefix}")
+ private String threadNamePrefix = "thinglinksAsync-";
+
+ @Autowired
+ private SuRejectHandle rejectHandle;
+
+ /**
+ * Broker服务全局共享异步线程池
+ */
+ @Bean("brokerAsync")
+ public Executor brokerAsync() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(corePoolSize);//核心线程数
+ executor.setMaxPoolSize(maxPoolSize);//最大线程数 cpu核数/(1-0.8)//cup核数*2//cup核数+1
+ //传参正值使用无界LinkedBlockingQueue
+ //其他传参使用不缓存SynchronousQueue
+ executor.setQueueCapacity(queueCapacity);//队列长度(超过队列长度无法存储,则开启最大线程数)
+ executor.setKeepAliveSeconds(keepAliveTime);//空闲线程最大存活时间 默认60s
+ executor.setThreadNamePrefix(threadNamePrefix + "brokerAsync-");//线程名前缀
+ executor.setRejectedExecutionHandler(rejectHandle);// 自定义任务丢失处理策略 该策略输出由scheduling-1打印
+ //设置线程池等待所有任务都完成再关闭
+ executor.setWaitForTasksToCompleteOnShutdown(true);
+ executor.setAwaitTerminationSeconds(keepAliveTime);
+ executor.initialize();
+ return executor;
+ }
+
+ /**
+ * MQTT设备消息消费异步线程池配置
+ */
+ @Bean("brokerAsync-mqttMsg")
+ public Executor brokerAsyncMqttMsg() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(corePoolSize);//核心线程数
+ executor.setMaxPoolSize(maxPoolSize);//最大线程数 cpu核数/(1-0.8)//cup核数*2//cup核数+1
+ //传参正值使用无界LinkedBlockingQueue
+ //其他传参使用不缓存SynchronousQueue
+ executor.setQueueCapacity(queueCapacity);//队列长度(超过队列长度无法存储,则开启最大线程数)
+ executor.setKeepAliveSeconds(keepAliveTime);//空闲线程最大存活时间 默认60s
+ executor.setThreadNamePrefix(threadNamePrefix + "brokerAsync-mqttMsg");//线程名前缀
+ executor.setRejectedExecutionHandler(rejectHandle);//自定义任务丢失处理策略 该策略输出由scheduling-1打印
+ executor.setWaitForTasksToCompleteOnShutdown(true);
+ executor.setAwaitTerminationSeconds(keepAliveTime);
+ executor.initialize();
+ return executor;
+ }
+
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaConsumerConfig.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaConsumerConfig.java
new file mode 100644
index 00000000..14ffa5ab
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaConsumerConfig.java
@@ -0,0 +1,109 @@
+package com.mqttsnet.thinglinks.broker.config;
+
+import org.apache.kafka.clients.consumer.ConsumerConfig;
+import org.apache.kafka.common.serialization.StringDeserializer;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
+import org.springframework.kafka.config.KafkaListenerContainerFactory;
+import org.springframework.kafka.core.ConsumerFactory;
+import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
+import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
+import org.springframework.kafka.listener.ContainerProperties;
+import org.springframework.kafka.support.serializer.JsonDeserializer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: KafkaConsumerConfig
+ * @packagename: com.mqttsnet.thinglinks.config.kafka
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-06-18 11:29
+ **/
+@Configuration
+public class KafkaConsumerConfig {
+
+
+ @Value("${spring.kafka.thingLinks.consumer.bootstrap-servers}")
+ private String bootstrapServers;
+ @Value("${spring.kafka.thingLinks.consumer.group-id}")
+ private String groupId;
+ @Value("${spring.kafka.thingLinks.consumer.enable-auto-commit}")
+ private boolean enableAutoCommit;
+ @Value("${spring.kafka.thingLinks.properties.session.timeout.ms}")
+ private String sessionTimeout;
+ @Value("${spring.kafka.thingLinks.properties.max.poll.interval.ms}")
+ private String maxPollIntervalTime;
+ @Value("${spring.kafka.thingLinks.consumer.max-poll-records}")
+ private String maxPollRecords;
+ @Value("${spring.kafka.thingLinks.consumer.auto-offset-reset}")
+ private String autoOffsetReset;
+ @Value("${spring.kafka.thingLinks.listener.concurrency}")
+ private Integer concurrency;
+ @Value("${spring.kafka.thingLinks.listener.missing-topics-fatal}")
+ private boolean missingTopicsFatal;
+ @Value("${spring.kafka.thingLinks.listener.poll-timeout}")
+ private long pollTimeout;
+
+ @Bean
+ public Map consumerConfigs() {
+
+ Map propsMap = new HashMap<>(16);
+ propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
+ propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
+ //是否自动提交偏移量,默认值是true,为了避免出现重复数据和数据丢失,可以把它设置为false,然后手动提交偏移量
+ propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit);
+ //自动提交的时间间隔,自动提交开启时生效
+ propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "2000");
+ //该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
+ //earliest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费分区的记录
+ //latest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据(在消费者启动之后生成的记录)
+ //none:当各分区都存在已提交的offset时,从提交的offset开始消费;只要有一个分区不存在已提交的offset,则抛出异常
+ propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset);
+ //两次poll之间的最大间隔,默认值为5分钟。如果超过这个间隔会触发reBalance
+ propsMap.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, maxPollIntervalTime);
+ //这个参数定义了poll方法最多可以拉取多少条消息,默认值为500。如果在拉取消息的时候新消息不足500条,那有多少返回多少;如果超过500条,每次只返回500。
+ //这个默认值在有些场景下太大,有些场景很难保证能够在5min内处理完500条消息,
+ //如果消费者无法在5分钟内处理完500条消息的话就会触发reBalance,
+ //然后这批消息会被分配到另一个消费者中,还是会处理不完,这样这批消息就永远也处理不完。
+ //要避免出现上述问题,提前评估好处理一条消息最长需要多少时间,然后覆盖默认的max.poll.records参数
+ //注:需要开启BatchListener批量监听才会生效,如果不开启BatchListener则不会出现reBalance情况
+ propsMap.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, maxPollRecords);
+ //当broker多久没有收到consumer的心跳请求后就触发reBalance,默认值是10s
+ propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sessionTimeout);
+ //序列化(建议使用Json,这种序列化方式可以无需额外配置传输实体类)
+ propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
+ propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
+ return propsMap;
+ }
+
+ @Bean
+ public ConsumerFactory consumerFactory() {
+
+ //配置消费者的 Json 反序列化的可信赖包,反序列化实体类需要
+ try (StringDeserializer stringDeserializer = new StringDeserializer()) {
+ return new DefaultKafkaConsumerFactory<>(consumerConfigs(), new StringDeserializer(), stringDeserializer);
+ }
+ }
+
+ @Bean
+ public KafkaListenerContainerFactory> kafkaListenerContainerFactory() {
+
+ ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>();
+ factory.setConsumerFactory(consumerFactory());
+ //在侦听器容器中运行的线程数,一般设置为 机器数*分区数
+ factory.setConcurrency(concurrency);
+ //消费监听接口监听的主题不存在时,默认会报错,所以设置为false忽略错误
+ factory.setMissingTopicsFatal(missingTopicsFatal);
+ //自动提交关闭,需要设置手动消息确认
+ factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
+ factory.getContainerProperties().setPollTimeout(pollTimeout);
+ //设置为批量监听,需要用List接收
+ factory.setBatchListener(true);
+ return factory;
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaProviderConfig.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaProviderConfig.java
new file mode 100644
index 00000000..5a2cca04
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaProviderConfig.java
@@ -0,0 +1,90 @@
+package com.mqttsnet.thinglinks.broker.config;
+
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.kafka.core.DefaultKafkaProducerFactory;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.core.ProducerFactory;
+import org.springframework.kafka.support.serializer.JsonSerializer;
+import org.springframework.kafka.transaction.KafkaTransactionManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: KafkaProviderConfig
+ * @packagename: com.mqttsnet.thinglinks.config.kafka
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-06-18 11:28
+ **/
+@Configuration
+public class KafkaProviderConfig {
+
+
+ @Value("${spring.kafka.thingLinks.producer.bootstrap-servers}")
+ private String bootstrapServers;
+ @Value("${spring.kafka.thingLinks.producer.transaction-id-prefix}")
+ private String transactionIdPrefix;
+ @Value("${spring.kafka.thingLinks.producer.acks}")
+ private String acks;
+ @Value("${spring.kafka.thingLinks.producer.retries}")
+ private String retries;
+ @Value("${spring.kafka.thingLinks.producer.batch-size}")
+ private String batchSize;
+ @Value("${spring.kafka.thingLinks.producer.buffer-memory}")
+ private String bufferMemory;
+
+ @Bean
+ public Map producerConfigs() {
+
+ Map props = new HashMap<>(16);
+ props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
+ //acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。
+ //acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
+ //acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
+ //开启事务必须设为all
+ props.put(ProducerConfig.ACKS_CONFIG, acks);
+ //发生错误后,消息重发的次数,开启事务必须大于0
+ props.put(ProducerConfig.RETRIES_CONFIG, retries);
+ //当多个消息发送到相同分区时,生产者会将消息打包到一起,以减少请求交互. 而不是一条条发送
+ //批次的大小可以通过batch.size 参数设置.默认是16KB
+ //较小的批次大小有可能降低吞吐量(批次大小为0则完全禁用批处理)。
+ //比如说,kafka里的消息5秒钟Batch才凑满了16KB,才能发送出去。那这些消息的延迟就是5秒钟
+ //实测batchSize这个参数没有用
+ props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize);
+ //有的时刻消息比较少,过了很久,比如5min也没有凑够16KB,这样延时就很大,所以需要一个参数. 再设置一个时间,到了这个时间,
+ //即使数据没达到16KB,也将这个批次发送出去
+ props.put(ProducerConfig.LINGER_MS_CONFIG, "5000");
+ //生产者内存缓冲区的大小
+ props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory);
+ //反序列化,和生产者的序列化方式对应
+ props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
+ props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
+ return props;
+ }
+
+ @Bean
+ public ProducerFactory producerFactory() {
+
+ DefaultKafkaProducerFactory factory = new DefaultKafkaProducerFactory<>(producerConfigs());
+ //开启事务,会导致 LINGER_MS_CONFIG 配置失效
+ factory.setTransactionIdPrefix(transactionIdPrefix);
+ return factory;
+ }
+
+ @Bean
+ public KafkaTransactionManager kafkaTransactionManager(ProducerFactory producerFactory) {
+
+ return new KafkaTransactionManager<>(producerFactory);
+ }
+
+ @Bean
+ public KafkaTemplate thingLinksKafkaTemplate() {
+
+ return new KafkaTemplate<>(producerFactory());
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/controller/MqttBrokerOpenController.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/controller/MqttBrokerOpenController.java
index fc23f856..64b5ad59 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/controller/MqttBrokerOpenController.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/controller/MqttBrokerOpenController.java
@@ -2,7 +2,7 @@
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
-import com.mqttsnet.thinglinks.broker.api.domain.model.PublishMessageRequest;
+import com.mqttsnet.thinglinks.broker.api.domain.vo.PublishMessageRequestVO;
import com.mqttsnet.thinglinks.broker.service.MqttBrokerService;
import com.mqttsnet.thinglinks.common.core.domain.R;
import io.swagger.annotations.Api;
@@ -40,15 +40,15 @@ public class MqttBrokerOpenController {
/**
* MQTT推送消息接口
*
- * @param publishMessageRequest 推送消息请求参数
+ * @param publishMessageRequestVO 推送消息请求参数
* @return {@link R} 结果
*/
@ApiOperation(value = "MQTT推送消息", notes = "根据提供的主题、服务质量等级、保留标志和消息内容推送MQTT消息")
@PostMapping("/sendMessage")
public R> sendMessage(@ApiParam(value = "推送消息请求参数", required = true)
- @RequestBody PublishMessageRequest publishMessageRequest) {
- log.info("MQTT Broker publish {}", publishMessageRequest.toString());
- return R.ok(mqttBrokerService.publishMessage(publishMessageRequest));
+ @RequestBody PublishMessageRequestVO publishMessageRequestVO) {
+ log.info("MQTT Broker publish {}", publishMessageRequestVO.toString());
+ return R.ok(mqttBrokerService.publishMessage(publishMessageRequestVO));
}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttCloseEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttCloseEvent.java
new file mode 100644
index 00000000..b50b4864
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttCloseEvent.java
@@ -0,0 +1,31 @@
+package com.mqttsnet.thinglinks.broker.mqs.event;
+
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description:
+ * @packagename: com.mqttsnet.thinglinks.mqtt.event
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 01:52
+ **/
+public class MqttCloseEvent extends ApplicationEvent {
+ private String message;
+ private MqttEventEnum eventType;
+
+ public MqttCloseEvent(Object source, MqttEventEnum eventType, String message) {
+ super(source);
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public MqttEventEnum getEventType() {
+ return eventType;
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttConnectEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttConnectEvent.java
new file mode 100644
index 00000000..090cdd45
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttConnectEvent.java
@@ -0,0 +1,31 @@
+package com.mqttsnet.thinglinks.broker.mqs.event;
+
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description:
+ * @packagename: com.mqttsnet.thinglinks.mqtt.event
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 01:15
+ **/
+public class MqttConnectEvent extends ApplicationEvent {
+ private String message;
+ private MqttEventEnum eventType;
+
+ public MqttConnectEvent(Object source, MqttEventEnum eventType, String message) {
+ super(source);
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public MqttEventEnum getEventType() {
+ return eventType;
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttDisconnectEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttDisconnectEvent.java
new file mode 100644
index 00000000..95c2aedf
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttDisconnectEvent.java
@@ -0,0 +1,31 @@
+package com.mqttsnet.thinglinks.broker.mqs.event;
+
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MqttDisconnectEvent
+ * @packagename: com.mqttsnet.thinglinks.mqtt.event
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 01:52
+ **/
+public class MqttDisconnectEvent extends ApplicationEvent {
+ private String message;
+ private MqttEventEnum eventType;
+
+ public MqttDisconnectEvent(Object source, MqttEventEnum eventType, String message) {
+ super(source);
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public MqttEventEnum getEventType() {
+ return eventType;
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPingEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPingEvent.java
new file mode 100644
index 00000000..9fd98460
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPingEvent.java
@@ -0,0 +1,31 @@
+package com.mqttsnet.thinglinks.broker.mqs.event;
+
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MqttPingEvent
+ * @packagename: com.mqttsnet.thinglinks.mqtt.event
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 01:53
+ **/
+public class MqttPingEvent extends ApplicationEvent {
+ private String message;
+ private MqttEventEnum eventType;
+
+ public MqttPingEvent(Object source, MqttEventEnum eventType, String message) {
+ super(source);
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public MqttEventEnum getEventType() {
+ return eventType;
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPublishEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPublishEvent.java
new file mode 100644
index 00000000..d64d908f
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPublishEvent.java
@@ -0,0 +1,32 @@
+package com.mqttsnet.thinglinks.broker.mqs.event;
+
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MqttPublishEvent
+ * @packagename: com.mqttsnet.thinglinks.mqtt.event
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 01:13
+ **/
+public class MqttPublishEvent extends ApplicationEvent {
+ private String message;
+ private MqttEventEnum eventType;
+
+ public MqttPublishEvent(Object source, MqttEventEnum eventType, String message) {
+ super(source);
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public MqttEventEnum getEventType() {
+ return eventType;
+ }
+}
+
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttSubscribeEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttSubscribeEvent.java
new file mode 100644
index 00000000..82f2293a
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttSubscribeEvent.java
@@ -0,0 +1,31 @@
+package com.mqttsnet.thinglinks.broker.mqs.event;
+
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MqttSubscribeEvent
+ * @packagename: com.mqttsnet.thinglinks.mqtt.event
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 01:52
+ **/
+public class MqttSubscribeEvent extends ApplicationEvent {
+ private String message;
+ private MqttEventEnum eventType;
+
+ public MqttSubscribeEvent(Object source, MqttEventEnum eventType, String message) {
+ super(source);
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public MqttEventEnum getEventType() {
+ return eventType;
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttUnsubscribeEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttUnsubscribeEvent.java
new file mode 100644
index 00000000..82987257
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttUnsubscribeEvent.java
@@ -0,0 +1,32 @@
+package com.mqttsnet.thinglinks.broker.mqs.event;
+
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MqttUnsubscribeEvent
+ * @packagename: com.mqttsnet.thinglinks.mqtt.event
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 01:53
+ **/
+public class MqttUnsubscribeEvent extends ApplicationEvent {
+ private String message;
+ private MqttEventEnum eventType;
+
+ public MqttUnsubscribeEvent(Object source, MqttEventEnum eventType, String message) {
+ super(source);
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public MqttEventEnum getEventType() {
+ return eventType;
+ }
+}
+
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttCloseEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttCloseEventListener.java
new file mode 100644
index 00000000..057d4375
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttCloseEventListener.java
@@ -0,0 +1,81 @@
+package com.mqttsnet.thinglinks.broker.mqs.event.listener;
+
+import com.google.gson.Gson;
+import com.mqttsnet.thinglinks.broker.mqs.event.MqttCloseEvent;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventActionService;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
+import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import com.mqttsnet.thinglinks.link.api.domain.device.enumeration.DeviceActionTypeEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MQTT CLOSE事件监听器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.listener
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 00:42
+ **/
+@Component
+@Slf4j
+public class MqttCloseEventListener {
+
+ @Resource
+ private RemoteDeviceService remoteDeviceService;
+
+ @Autowired
+ private MqttEventActionService mqttEventActionService;
+
+
+ /**
+ * 发布MQTT CLOSE事件
+ *
+ * @param event 事件消息
+ */
+ @EventListener
+ @Async("brokerAsync-mqttMsg")
+ public void publishMqttCloseEvent(MqttCloseEvent event) {
+ log.info("Publishing MQTT CLOSE event: message={}", event.getMessage());
+ Gson gson = new Gson();
+ Map map = new HashMap<>();
+ map = gson.fromJson(event.getMessage(), map.getClass());
+ String clientId = String.valueOf(map.get("clientId"));
+
+ // TODO 从缓存中获取设备信息 校验设备是否存在
+
+ // 构造设备对象并设置客户端ID和连接状态
+ Device deviceToUpdate = new Device()
+ .setClientId(clientId)
+ .setConnectStatus(DeviceConnectStatusEnum.OFFLINE.getKey());
+
+ // 更新设备连接状态
+ R updateDeviceConnectionStatus = remoteDeviceService.updateConnectStatusByClientId(deviceToUpdate);
+
+ // 检查更新操作的结果
+ if (ResultEnum.SUCCESS.getCode() != updateDeviceConnectionStatus.getCode()) {
+ log.error("Failed to update the device connection status to OFFLINE, clientId={}", clientId);
+ return;
+ }
+
+
+ String describable = Optional.ofNullable(DeviceConnectStatusEnum.OFFLINE.getKey())
+ .flatMap(DeviceConnectStatusEnum::fromValue)
+ .map(DeviceConnectStatusEnum::getKey)
+ .map(desc -> "The device connection status is updated to " + desc)
+ .orElse("The device connection status is updated to OFFLINE");
+
+ mqttEventActionService.saveMqttEventAction(event.getMessage(), DeviceActionTypeEnum.CLOSE, describable);
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttConnectEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttConnectEventListener.java
new file mode 100644
index 00000000..361047e2
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttConnectEventListener.java
@@ -0,0 +1,81 @@
+package com.mqttsnet.thinglinks.broker.mqs.event.listener;
+
+import com.google.gson.Gson;
+import com.mqttsnet.thinglinks.broker.mqs.event.MqttConnectEvent;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventActionService;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
+import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import com.mqttsnet.thinglinks.link.api.domain.device.enumeration.DeviceActionTypeEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MQTT CONNECT事件监听器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.listener
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 00:36
+ **/
+@Component
+@Slf4j
+public class MqttConnectEventListener {
+
+ @Resource
+ private RemoteDeviceService remoteDeviceService;
+
+ @Autowired
+ private MqttEventActionService mqttEventActionService;
+
+
+ /**
+ * 发布MQTT CONNECT事件
+ *
+ * @param event 事件消息
+ */
+ @EventListener
+ @Async("brokerAsync-mqttMsg")
+ public void publishMqttCloseEvent(MqttConnectEvent event) {
+ log.info("Publishing MQTT CONNECT event: message={}", event.getMessage());
+ Gson gson = new Gson();
+ Map map = new HashMap<>();
+ map = gson.fromJson(event.getMessage(), map.getClass());
+ String clientId = String.valueOf(map.get("clientId"));
+
+ // TODO 从缓存中获取设备信息 校验设备是否存在
+
+ // 构造设备对象并设置客户端ID和连接状态
+ Device deviceToUpdate = new Device()
+ .setClientId(clientId)
+ .setConnectStatus(DeviceConnectStatusEnum.ONLINE.getKey());
+
+ // 更新设备连接状态
+ R updateDeviceConnectionStatus = remoteDeviceService.updateConnectStatusByClientId(deviceToUpdate);
+
+ // 检查更新操作的结果
+ if (ResultEnum.SUCCESS.getCode() != updateDeviceConnectionStatus.getCode()) {
+ log.error("Failed to update the device connection status to OFFLINE, clientId={}", clientId);
+ return;
+ }
+
+
+ String describable = Optional.ofNullable(DeviceConnectStatusEnum.ONLINE.getKey())
+ .flatMap(DeviceConnectStatusEnum::fromValue)
+ .map(DeviceConnectStatusEnum::getKey)
+ .map(desc -> "The device connection status is updated to " + desc)
+ .orElse("The device connection status is updated to ONLINE");
+
+ mqttEventActionService.saveMqttEventAction(event.getMessage(), DeviceActionTypeEnum.CONNECT, describable);
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttDisconnectEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttDisconnectEventListener.java
new file mode 100644
index 00000000..524e0ae4
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttDisconnectEventListener.java
@@ -0,0 +1,81 @@
+package com.mqttsnet.thinglinks.broker.mqs.event.listener;
+
+import com.google.gson.Gson;
+import com.mqttsnet.thinglinks.broker.mqs.event.MqttDisconnectEvent;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventActionService;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
+import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import com.mqttsnet.thinglinks.link.api.domain.device.enumeration.DeviceActionTypeEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MQTT DISCONNECT事件监听器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.listener
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 00:45
+ **/
+@Component
+@Slf4j
+public class MqttDisconnectEventListener {
+
+ @Resource
+ private RemoteDeviceService remoteDeviceService;
+
+ @Autowired
+ private MqttEventActionService mqttEventActionService;
+
+
+ /**
+ * 发布MQTT DISCONNECT事件
+ *
+ * @param event 事件消息
+ */
+ @EventListener
+ @Async("brokerAsync-mqttMsg")
+ public void publishMqttDisconnectEvent(MqttDisconnectEvent event) {
+ log.info("Publishing MQTT DISCONNECT event: message={}", event.getMessage());
+ Gson gson = new Gson();
+ Map map = new HashMap<>();
+ map = gson.fromJson(event.getMessage(), map.getClass());
+ String clientId = String.valueOf(map.get("clientId"));
+
+ // TODO 从缓存中获取设备信息 校验设备是否存在
+
+ // 构造设备对象并设置客户端ID和连接状态
+ Device deviceToUpdate = new Device()
+ .setClientId(clientId)
+ .setConnectStatus(DeviceConnectStatusEnum.OFFLINE.getKey());
+
+ // 更新设备连接状态
+ R updateDeviceConnectionStatus = remoteDeviceService.updateConnectStatusByClientId(deviceToUpdate);
+
+ // 检查更新操作的结果
+ if (ResultEnum.SUCCESS.getCode() != updateDeviceConnectionStatus.getCode()) {
+ log.error("Failed to update the device connection status to OFFLINE, clientId={}", clientId);
+ return;
+ }
+
+
+ String describable = Optional.ofNullable(DeviceConnectStatusEnum.OFFLINE.getKey())
+ .flatMap(DeviceConnectStatusEnum::fromValue)
+ .map(DeviceConnectStatusEnum::getKey)
+ .map(desc -> "The device connection status is updated to " + desc)
+ .orElse("The device connection status is updated to OFFLINE");
+
+ mqttEventActionService.saveMqttEventAction(event.getMessage(), DeviceActionTypeEnum.DISCONNECT, describable);
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPingEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPingEventListener.java
new file mode 100644
index 00000000..d0598b4e
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPingEventListener.java
@@ -0,0 +1,32 @@
+package com.mqttsnet.thinglinks.broker.mqs.event.listener;
+
+import com.mqttsnet.thinglinks.broker.mqs.event.MqttPingEvent;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MQTT PING事件监听器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.listener
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 00:48
+ **/
+@Component
+@Slf4j
+public class MqttPingEventListener {
+
+ /**
+ * 发布MQTT PING事件
+ *
+ * @param event 事件消息
+ */
+ @EventListener
+ @Async("brokerAsync-mqttMsg")
+ public void publishMqttPingEvent(MqttPingEvent event) {
+ log.info("Publishing MQTT PING event: message={}", event.getMessage());
+ // TODO: 处理MQTT PING事件
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPublishEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPublishEventListener.java
new file mode 100644
index 00000000..8862421c
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPublishEventListener.java
@@ -0,0 +1,58 @@
+package com.mqttsnet.thinglinks.broker.mqs.event.listener;
+
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.mqttsnet.thinglinks.broker.mqs.event.MqttPublishEvent;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.event.MqttMessageEvent;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MqttPublish事件监听器
+ * @packagename: com.mqttsnet.thinglinks.consumer.mqtt.listener
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 00:12
+ **/
+@Component
+@Slf4j
+public class MqttPublishEventListener {
+
+ @Autowired
+ private ApplicationEventPublisher publisher;
+
+ /**
+ * 处理MQTT PUBLISH事件
+ *
+ * @param event 事件消息
+ */
+ @EventListener
+ @Async("brokerAsync-mqttMsg")
+ public void handleMqttPublishEvent(MqttPublishEvent event) {
+ log.info("Received MQTT PUBLISH event: message={}", event.getMessage());
+ // 处理PUBLISH事件
+ if (StringUtils.isEmpty(event.getMessage()) && JSONUtil.isTypeJSON(event.getMessage())) {
+ log.warn("The message is empty and ignored");
+ return;
+ }
+ JSONObject mqttMessage = JSON.parseObject(event.getMessage());
+ String topic = mqttMessage.getString("topic");
+ String qos = mqttMessage.getString("qos");
+ String body = mqttMessage.getString("body");
+ String time = mqttMessage.getString("time");
+ if (!JSONUtil.isTypeJSON(body)) {
+ log.error("Topic:{},The body is empty and ignored", topic);
+ return;
+ }
+ log.info("MqttPublishEventListener handleMqttPublishEvent mqttMessage topic:{}, qos:{}, body:{}, time:{}", topic, qos, body, time);
+ // 发布MQTT消息事件
+ publisher.publishEvent(new MqttMessageEvent(this, topic, qos, body, time));
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttSubscribeEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttSubscribeEventListener.java
new file mode 100644
index 00000000..e2ec4041
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttSubscribeEventListener.java
@@ -0,0 +1,38 @@
+package com.mqttsnet.thinglinks.broker.mqs.event.listener;
+
+import com.mqttsnet.thinglinks.broker.mqs.event.MqttSubscribeEvent;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventActionService;
+import com.mqttsnet.thinglinks.link.api.domain.device.enumeration.DeviceActionTypeEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MQTT SUBSCRIBE事件监听器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.listener
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 00:46
+ **/
+@Component
+@Slf4j
+public class MqttSubscribeEventListener {
+
+ @Autowired
+ private MqttEventActionService mqttEventActionService;
+
+ /**
+ * 发布MQTT SUBSCRIBE事件
+ *
+ * @param event 事件消息
+ */
+ @EventListener
+ @Async("brokerAsync-mqttMsg")
+ public void publishMqttSubscribeEvent(MqttSubscribeEvent event) {
+ log.info("Publishing MQTT SUBSCRIBE event: message={}", event.getMessage());
+ mqttEventActionService.saveMqttEventAction(event.getMessage(), DeviceActionTypeEnum.SUBSCRIBE, DeviceActionTypeEnum.SUBSCRIBE.getDescription());
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttUnsubscribeEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttUnsubscribeEventListener.java
new file mode 100644
index 00000000..c264ffdb
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttUnsubscribeEventListener.java
@@ -0,0 +1,38 @@
+package com.mqttsnet.thinglinks.broker.mqs.event.listener;
+
+import com.mqttsnet.thinglinks.broker.mqs.event.MqttUnsubscribeEvent;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventActionService;
+import com.mqttsnet.thinglinks.link.api.domain.device.enumeration.DeviceActionTypeEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MQTT UNSUBSCRIBE事件监听器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.listener
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 00:48
+ **/
+@Component
+@Slf4j
+public class MqttUnsubscribeEventListener {
+
+ @Autowired
+ private MqttEventActionService mqttEventActionService;
+
+ /**
+ * 发布MQTT UNSUBSCRIBE事件
+ *
+ * @param event 事件消息
+ */
+ @EventListener
+ @Async("brokerAsync-mqttMsg")
+ public void publishMqttUnsubscribeEvent(MqttUnsubscribeEvent event) {
+ log.info("Publishing MQTT UNSUBSCRIBE event: message={}", event.getMessage());
+ mqttEventActionService.saveMqttEventAction(event.getMessage(), DeviceActionTypeEnum.UNSUBSCRIBE, DeviceActionTypeEnum.UNSUBSCRIBE.getDescription());
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/publisher/MqttEventPublisher.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/publisher/MqttEventPublisher.java
new file mode 100644
index 00000000..07167d16
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/publisher/MqttEventPublisher.java
@@ -0,0 +1,59 @@
+package com.mqttsnet.thinglinks.broker.mqs.event.publisher;
+
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import com.mqttsnet.thinglinks.broker.mqs.event.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MQTT事件发布器 用于发布MQTT事件 TODO MqttEventEnum 事件枚举类 用于定义MQTT事件 预留
+ * @packagename: com.mqttsnet.thinglinks.consumer.mqtt.publisher
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 00:07
+ **/
+@Component
+@Slf4j
+public class MqttEventPublisher {
+ @Autowired
+ private ApplicationEventPublisher eventPublisher;
+
+ public void publishMqttConnectEvent(MqttEventEnum eventEnum, String message) {
+ log.info("Publishing MQTT CONNECT event: message={}", message);
+ eventPublisher.publishEvent(new MqttConnectEvent(this, eventEnum, message));
+ }
+
+ public void publishMqttCloseEvent(MqttEventEnum eventEnum, String message) {
+ log.info("Publishing MQTT CLOSE event: message={}", message);
+ eventPublisher.publishEvent(new MqttCloseEvent(this, eventEnum, message));
+ }
+
+ public void publishMqttDisconnectEvent(MqttEventEnum eventEnum, String message) {
+ log.info("Publishing MQTT DISCONNECT event: message={}", message);
+ eventPublisher.publishEvent(new MqttDisconnectEvent(this, eventEnum, message));
+ }
+
+ public void publishMqttPublishEvent(MqttEventEnum eventEnum, String message) {
+ log.info("Publishing MQTT PUBLISH event: message={}", message);
+ eventPublisher.publishEvent(new MqttPublishEvent(this, eventEnum, message));
+ }
+
+ public void publishMqttSubscribeEvent(MqttEventEnum eventEnum, String message) {
+ log.info("Publishing MQTT SUBSCRIBE event: message={}", message);
+ eventPublisher.publishEvent(new MqttSubscribeEvent(this, eventEnum, message));
+ }
+
+ public void publishMqttUnsubscribeEvent(MqttEventEnum eventEnum, String message) {
+ log.info("Publishing MQTT UNSUBSCRIBE event: message={}", message);
+ eventPublisher.publishEvent(new MqttUnsubscribeEvent(this, eventEnum, message));
+ }
+
+ public void publishMqttPingEvent(MqttEventEnum eventEnum, String message) {
+ log.info("Publishing MQTT PING event: message={}", message);
+ eventPublisher.publishEvent(new MqttPingEvent(this, eventEnum, message));
+ }
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaProducerService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaProducerService.java
new file mode 100644
index 00000000..efb1fe4d
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaProducerService.java
@@ -0,0 +1,49 @@
+package com.mqttsnet.thinglinks.broker.mqs.handler.kafka;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.support.SendResult;
+import org.springframework.stereotype.Service;
+import org.springframework.util.concurrent.ListenableFuture;
+import org.springframework.util.concurrent.ListenableFutureCallback;
+
+/**
+ * @Description: kafka生产者
+ * @Author: ShiHuan Sun
+ * @E-mail: 13733918655@163.com
+ * @CreateDate: 2023/01/06$ 16:02$
+ * @UpdateUser: ShiHuan Sun
+ * @UpdateDate: 2023/01/06$ 16:02$
+ * @UpdateRemark: 修改内容
+ * @Version: 1.0
+ */
+@Service
+@Slf4j
+public class KafkaProducerService {
+
+ @Autowired
+ @Qualifier("thingLinksKafkaTemplate")
+ private KafkaTemplate thingLinksKafkaTemplate;
+
+
+ public void thingLinksKafkaTemplateSendMsg(String topic, String msg) {
+ log.info("thingLinksKafkaTemplate sendMsg ,topic:{},msg:{}", topic, msg);
+
+ ListenableFuture> sendMsg = thingLinksKafkaTemplate.send(topic, msg);
+ //消息确认
+ sendMsg.addCallback(new ListenableFutureCallback>() {
+ @Override
+ public void onFailure(Throwable throwable) {
+ log.error("send error,ex:{},topic:{},msg:{}", throwable, topic, msg);
+ }
+
+ @Override
+ public void onSuccess(SendResult stringStringSendResult) {
+ log.info("send success,topic:{},msg:{}", topic, msg);
+ }
+ });
+ log.info("kafka send end!");
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaSendResultHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaSendResultHandler.java
new file mode 100644
index 00000000..b0da2eeb
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaSendResultHandler.java
@@ -0,0 +1,34 @@
+package com.mqttsnet.thinglinks.broker.mqs.handler.kafka;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.apache.kafka.clients.producer.RecordMetadata;
+import org.springframework.kafka.support.ProducerListener;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: kafka消息发送回调
+ * @packagename: com.mqttsnet.thinglinks.common.kafka.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-06-18 11:39
+ **/
+@Slf4j
+@Component
+public class KafkaSendResultHandler implements ProducerListener {
+
+
+ @Override
+ public void onSuccess(ProducerRecord producerRecord, RecordMetadata recordMetadata) {
+
+ log.info("消息发送成功:{}", producerRecord.toString());
+ }
+
+ @Override
+ public void onError(ProducerRecord producerRecord, @Nullable RecordMetadata recordMetadata, Exception exception) {
+
+ log.error("消息发送失败:{},{}", producerRecord.toString(), exception.getMessage());
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MqttMessageKafkaConsumerHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MqttMessageKafkaConsumerHandler.java
new file mode 100644
index 00000000..2e63b4fc
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MqttMessageKafkaConsumerHandler.java
@@ -0,0 +1,131 @@
+package com.mqttsnet.thinglinks.broker.mqs.handler.kafka;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.mqttsnet.thinglinks.broker.api.domain.enumeration.MqttEventEnum;
+import com.mqttsnet.thinglinks.broker.mqs.event.publisher.MqttEventPublisher;
+import com.mqttsnet.thinglinks.common.core.mqs.ConsumerTopicConstant;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.annotation.KafkaHandler;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.kafka.support.Acknowledgment;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: Mqtt Message kafka监听消息
+ * @packagename: com.mqttsnet.thinglinks.kafka
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-06-18 11:46
+ **/
+@Slf4j
+@Component
+public class MqttMessageKafkaConsumerHandler {
+
+ @Autowired
+ private MqttEventPublisher eventPublisher;
+
+ @Autowired
+ private CacheDataHelper cacheDataHelper;
+
+ /**
+ * 监听kafka消息(批量)
+ *
+ * @param records kafka的批量消息,用consumerRecord可以接收到更详细的信息,也可以用String message只接收消息
+ * @param ack kafka的消息确认
+ */
+ @KafkaListener(topics = {ConsumerTopicConstant.Mqtt.THINGLINKS_MQS_MQTT_MSG,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_CLIENT_CONNECTED_TOPIC,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_CLIENT_DISCONNECTED_TOPIC,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_SERVER_CONNECTED_TOPIC,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_DEVICE_KICKED_TOPIC,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_SUBSCRIPTION_ACKED_TOPIC,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_UNSUBSCRIPTION_ACKED_TOPIC,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_DISTRIBUTION_ERROR_TOPIC,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_DISTRIBUTION_COMPLETED_TOPIC,
+ ConsumerTopicConstant.Mqtt.THINGLINKS_PING_REQ_TOPIC
+ }, errorHandler = "myKafkaListenerErrorHandler", containerFactory = "kafkaListenerContainerFactory")
+ @KafkaHandler
+ public void handleBatchMessages(List> records, Acknowledgment ack) {
+ try {
+ // 用于测试异常处理
+ // int i = 1 / 0;
+ log.info("handleBatchMessages Listener, Thread ID:{}, records size:{}", Thread.currentThread().getId(), records.size());
+ for (ConsumerRecord, ?> record : records) {
+ Optional> kafkaMessage = Optional.ofNullable(record.value());
+ if (!kafkaMessage.isPresent()) {
+ log.error("topic:{},报文体为空或数据格式有误已忽略" + record.topic());
+ return;
+ }
+ String message = record.value().toString();
+ String topic = record.topic();
+ log.info("handleBatchMessages--> topic={} Received message={}", topic, message);
+ processMessage(message);
+ }
+ } finally {
+ // 手动确认
+ ack.acknowledge();
+ }
+ }
+
+ /**
+ * 处理消息
+ *
+ * @param message 消息记录
+ */
+ private void processMessage(String message) {
+ log.info("ThingLinks物联网平台数据消费-->Received message={}", message);
+ try {
+ JSONObject thinglinksMessage = JSON.parseObject(String.valueOf(message));
+ String eventStr = Optional.ofNullable(thinglinksMessage.getString("event"))
+ .orElse("");
+ Long tenantId = Optional.ofNullable(thinglinksMessage.getString("tenantId"))
+ .filter(StringUtils::isNotBlank)
+ .map(Long::valueOf)
+ .orElse(null);
+ if (StringUtils.isEmpty(eventStr) || tenantId == null) {
+ log.warn("event or tenantId cannot be empty {}", eventStr);
+ return;
+ }
+ Optional optionalEvent = MqttEventEnum.getMqttEventEnum(thinglinksMessage.get("event").toString());
+ optionalEvent.ifPresent(event -> {
+ switch (event) {
+ case CONNECT:
+ eventPublisher.publishMqttConnectEvent(MqttEventEnum.CONNECT, thinglinksMessage.toJSONString());
+ break;
+ case CLOSE:
+ eventPublisher.publishMqttCloseEvent(MqttEventEnum.CLOSE, thinglinksMessage.toJSONString());
+ break;
+ case DISCONNECT:
+ eventPublisher.publishMqttDisconnectEvent(MqttEventEnum.DISCONNECT, thinglinksMessage.toJSONString());
+ break;
+ case PUBLISH:
+ eventPublisher.publishMqttPublishEvent(MqttEventEnum.PUBLISH, thinglinksMessage.toJSONString());
+ break;
+ case SUBSCRIBE:
+ eventPublisher.publishMqttSubscribeEvent(MqttEventEnum.SUBSCRIBE, thinglinksMessage.toJSONString());
+ break;
+ case UNSUBSCRIBE:
+ eventPublisher.publishMqttUnsubscribeEvent(MqttEventEnum.UNSUBSCRIBE, thinglinksMessage.toJSONString());
+ break;
+ case PING:
+ eventPublisher.publishMqttPingEvent(MqttEventEnum.PING, thinglinksMessage.toJSONString());
+ break;
+ default:
+ break;
+ }
+ });
+ } catch (Exception e) {
+ log.error("ThingLinks物联网平台数据消费-->消费失败,失败原因:{}", e.getMessage());
+ }
+ }
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MyKafkaListenerErrorHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MyKafkaListenerErrorHandler.java
new file mode 100644
index 00000000..e11696ad
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MyKafkaListenerErrorHandler.java
@@ -0,0 +1,38 @@
+package com.mqttsnet.thinglinks.broker.mqs.handler.kafka;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.kafka.clients.consumer.Consumer;
+import org.springframework.kafka.listener.KafkaListenerErrorHandler;
+import org.springframework.kafka.listener.ListenerExecutionFailedException;
+import org.springframework.lang.NonNull;
+import org.springframework.messaging.Message;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: kafkaListener异常处理
+ * @packagename: com.mqttsnet.thinglinks.common.kafka.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-06-18 11:44
+ **/
+@Slf4j
+@Component
+public class MyKafkaListenerErrorHandler implements KafkaListenerErrorHandler {
+
+ @Override
+ @NonNull
+ public Object handleError(@NonNull Message> message, @NonNull ListenerExecutionFailedException exception) {
+ log.error("Error handling message: {}", message, exception);
+ return new Object();
+ }
+
+ @Override
+ @NonNull
+ public Object handleError(@NonNull Message> message, @NonNull ListenerExecutionFailedException exception, Consumer, ?> consumer) {
+ log.error("Error handling message: {}", message, exception);
+ log.info("Consumer details: {}", consumer.groupMetadata());
+ log.info("Listener topic: {}", consumer.listTopics());
+ return KafkaListenerErrorHandler.super.handleError(message, exception, consumer);
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/AddSubDeviceHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/AddSubDeviceHandler.java
new file mode 100644
index 00000000..5b8e5644
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/AddSubDeviceHandler.java
@@ -0,0 +1,118 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.basic.protocol.model.ProtocolDataMessageDTO;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoAddSubDeviceParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 处理ADD_SUB_DEVICE主题
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 22:59
+ **/
+@Slf4j
+@Service
+public class AddSubDeviceHandler extends AbstractMessageHandler implements TopicHandler {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ public AddSubDeviceHandler(CacheDataHelper cacheDataHelper,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ }
+
+ /**
+ * @param topic the MQTT topic the message was received on.
+ * @param qos the quality of service level of the message.
+ * @param body the payload of the message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ if (!protocolMessageAdapter.validateProtocolData(body)) {
+ log.warn("The protocol format is incorrect");
+ return;
+ }
+ // 解析Topic
+ Map stringStringMap = protocolMessageAdapter.extractVariables(topic);
+ String version = stringStringMap.get("version");
+ String deviceId = stringStringMap.get("deviceId");
+
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ log.warn("Device with ID {} not found.", deviceId);
+ return;
+ }
+
+ try {
+ ProtocolDataMessageDTO protocolDataMessageDTO = protocolMessageAdapter.parseProtocolDataMessage(body);
+ // 构造 EncryptionDetails 对象
+ EncryptionDetailsDTO encryptionDetailsDTO = EncryptionDetailsDTO.builder()
+ .signKey(deviceCacheVO.getSignKey())
+ .encryptKey(deviceCacheVO.getEncryptKey())
+ .encryptVector(deviceCacheVO.getEncryptVector())
+ .build();
+ String dataBody = protocolMessageAdapter.decryptMessage(body, encryptionDetailsDTO);
+
+ // 解析body
+ TopoAddSubDeviceParam topoAddSubDeviceParam = JSON.toJavaObject(JSON.parseObject(dataBody), TopoAddSubDeviceParam.class);
+ topoAddSubDeviceParam.setGatewayIdentification(deviceId);
+ String resultDataBody = processingTopicMessage(topoAddSubDeviceParam);
+
+ // 处理返回结果
+ ProtocolDataMessageDTO handleResult = protocolMessageAdapter.buildResponse(protocolDataMessageDTO, resultDataBody, encryptionDetailsDTO);
+
+ // 根据请求主题确定响应主题
+ String responseTopic = "/topo/addResponse";
+ // 生成响应主题字符串
+ String responseTopicStr = generateResponseTopic(version, deviceId, responseTopic);
+
+ // 序列化 handleResult 对象为 JSON 字符串
+ String resultData = objectMapper.writeValueAsString(handleResult);
+
+ // 推送消息到 MQTT 通知设备添加子设备成功&失败
+ sendMessage(responseTopicStr, qos, resultData, String.valueOf(deviceCacheVO.getAppId()));
+ } catch (Exception e) {
+ log.error("Failed to decrypt the message", e);
+ }
+ }
+
+ /**
+ * Processes the message received on the /topo/add Topic for adding a sub-device to a gateway device.
+ *
+ * @param topoAddSubDeviceParam The data for adding a sub-device.
+ * @return The JSON representation of the processing result.
+ * @throws Exception if there is an issue processing the message.
+ */
+ @Override
+ protected String processingTopicMessage(Object topoAddSubDeviceParam) throws Exception {
+ if (!(topoAddSubDeviceParam instanceof TopoAddSubDeviceParam)) {
+ throw new IllegalArgumentException("Invalid parameter type for adding sub-device");
+ }
+
+ TopoAddSubDeviceParam addParam = (TopoAddSubDeviceParam) topoAddSubDeviceParam;
+ R mqttTopoAddDeviceResultVOR = remoteDeviceService.saveSubDeviceByMqtt(addParam);
+
+ log.info("Processing /topo/add Topic result: {}", JSON.toJSONString(mqttTopoAddDeviceResultVOR));
+ return JSON.toJSONString(mqttTopoAddDeviceResultVOR.getData());
+ }
+
+
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/CommandResponseHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/CommandResponseHandler.java
new file mode 100644
index 00000000..9be09dae
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/CommandResponseHandler.java
@@ -0,0 +1,78 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventCommandService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 处理COMMAND_RESPONSE主题
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 23:00
+ **/
+@Slf4j
+@Service
+public class CommandResponseHandler extends AbstractMessageHandler implements TopicHandler {
+ public CommandResponseHandler(CacheDataHelper cacheDataHelper,
+ DeviceOpenAnyTenantApi deviceOpenAnyTenantApi,
+ MqttBrokerOpenAnyTenantApi mqttBrokerOpenAnyTenantApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, deviceOpenAnyTenantApi, mqttBrokerOpenAnyTenantApi, protocolMessageAdapter);
+ }
+
+ @Autowired
+ private MqttEventCommandService mqttEventCommandService;
+
+ /**
+ * Handles MQTT messages, decrypts them, and processes the command.
+ *
+ * @param topic The topic the message was published to.
+ * @param qos The Quality of Service level of the message.
+ * @param body The raw body of the MQTT message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ if (!protocolMessageAdapter.validateProtocolData(body)) {
+ log.warn("The protocol format is incorrect");
+ return;
+ }
+
+ Map variables = protocolMessageAdapter.extractVariables(topic);
+ String deviceId = variables.get("deviceId");
+
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ log.warn("Device with ID {} not found.", deviceId);
+ return;
+ }
+
+ try {
+ EncryptionDetailsDTO encryptionDetailsDTO = EncryptionDetailsDTO.builder()
+ .signKey(deviceCacheVO.getSignKey())
+ .encryptKey(deviceCacheVO.getEncryptKey())
+ .encryptVector(deviceCacheVO.getEncryptVector())
+ .build();
+ String decryptedBody = protocolMessageAdapter.decryptMessage(body, encryptionDetailsDTO);
+ mqttEventCommandService.processCommand(deviceCacheVO, decryptedBody);
+ } catch (Exception e) {
+ log.error("Failed to decrypt the message", e);
+ }
+ }
+
+
+ @Override
+ protected String processingTopicMessage(Object messageParam) throws Exception {
+ return null;
+ }
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DefaultHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DefaultHandler.java
new file mode 100644
index 00000000..5164ebca
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DefaultHandler.java
@@ -0,0 +1,28 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 其他默认Topic处理器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 22:55
+ **/
+@Service
+@Slf4j
+public class DefaultHandler implements TopicHandler {
+
+ /**
+ * @param topic the MQTT topic the message was received on.
+ * @param qos the quality of service level of the message.
+ * @param body the payload of the message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ // 处理默认情况的逻辑
+ log.info("处理默认情况的逻辑,topic:{},qos:{},body:{}", topic, qos, body);
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeleteSubDeviceHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeleteSubDeviceHandler.java
new file mode 100644
index 00000000..df94f290
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeleteSubDeviceHandler.java
@@ -0,0 +1,110 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.basic.protocol.model.ProtocolDataMessageDTO;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoDeleteSubDeviceParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 处理DELETE_SUB_DEVICE主题
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 22:59
+ **/
+@Slf4j
+@Service
+public class DeleteSubDeviceHandler extends AbstractMessageHandler implements TopicHandler {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ public DeleteSubDeviceHandler(CacheDataHelper cacheDataHelper,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ }
+
+ /**
+ * @param topic the MQTT topic the message was received on.
+ * @param qos the quality of service level of the message.
+ * @param body the payload of the message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ if (!protocolMessageAdapter.validateProtocolData(body)) {
+ log.warn("The protocol format is incorrect");
+ return;
+ }
+
+ // Extract variables from the topic
+ Map stringStringMap = protocolMessageAdapter.extractVariables(topic);
+ String version = stringStringMap.get("version");
+ String deviceId = stringStringMap.get("deviceId");
+
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ return;
+ }
+
+ try {
+ ProtocolDataMessageDTO protocolDataMessageDTO = protocolMessageAdapter.parseProtocolDataMessage(body);
+ // 构造 EncryptionDetails 对象
+ EncryptionDetailsDTO encryptionDetailsDTO = EncryptionDetailsDTO.builder()
+ .signKey(deviceCacheVO.getSignKey())
+ .encryptKey(deviceCacheVO.getEncryptKey())
+ .encryptVector(deviceCacheVO.getEncryptVector())
+ .build();
+ String dataBody = protocolMessageAdapter.decryptMessage(body, encryptionDetailsDTO);
+
+ // Parse body
+ TopoDeleteSubDeviceParam topoDeleteSubDeviceParam = JSON.toJavaObject(JSON.parseObject(dataBody), TopoDeleteSubDeviceParam.class);
+ topoDeleteSubDeviceParam.setGatewayIdentification(deviceId);
+ String resultDataBody = processingTopicMessage(topoDeleteSubDeviceParam);
+
+ // Handle result
+ ProtocolDataMessageDTO handleResult = protocolMessageAdapter.buildResponse(protocolDataMessageDTO, resultDataBody, encryptionDetailsDTO);
+
+ // Determine response topic based on request topic
+ String responseTopic = "/topo/deleteResponse";
+ // Generate response topic string
+ String responseTopicStr = generateResponseTopic(version, deviceId, responseTopic);
+
+ // 序列化 handleResult 对象为 JSON 字符串
+ String resultData = objectMapper.writeValueAsString(handleResult);
+
+ // Push message to MQTT to notify device of successful/failed sub-device deletion
+ sendMessage(responseTopicStr, qos, resultData, String.valueOf(deviceCacheVO.getAppId()));
+ } catch (Exception e) {
+ log.error("Failed to decrypt the message", e);
+ }
+ }
+
+ /**
+ * Process /topo/delete Topic for gateway device to delete sub-device
+ *
+ * @param topoDeleteSubDeviceParam delete device data
+ * @return Processing result json
+ */
+ @Override
+ protected String processingTopicMessage(Object topoDeleteSubDeviceParam) throws Exception {
+ R mqttTopoDeleteDeviceResultVOR = remoteDeviceService.deleteSubDeviceByMqtt((TopoDeleteSubDeviceParam) topoDeleteSubDeviceParam);
+ log.info("processingTopoDeleteTopic Processing result:{}", JSON.toJSONString(mqttTopoDeleteDeviceResultVOR));
+ return JSON.toJSONString(mqttTopoDeleteDeviceResultVOR.getData());
+ }
+}
+
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeviceDatasHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeviceDatasHandler.java
new file mode 100644
index 00000000..f4739c01
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeviceDatasHandler.java
@@ -0,0 +1,326 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSON;
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.basic.protocol.model.ProtocolDataMessageDTO;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductModelCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoDeviceDataReportParam;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 处理DEVICE_DATA主题
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 23:00
+ **/
+@Slf4j
+@Service
+public class DeviceDatasHandler extends AbstractMessageHandler implements TopicHandler {
+
+ public DeviceDatasHandler(CacheDataHelper cacheDataHelper,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ }
+
+ @Autowired
+ private TdsApi tdsApi;
+
+
+ /**
+ * @param topic the MQTT topic the message was received on.
+ * @param qos the quality of service level of the message.
+ * @param body the payload of the message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ if (!protocolMessageAdapter.validateProtocolData(body)) {
+ log.warn("The protocol format is incorrect");
+ return;
+ }
+
+ // Extract variables from the topic
+ Map stringStringMap = protocolMessageAdapter.extractVariables(topic);
+ String version = stringStringMap.get("version");
+ String deviceId = stringStringMap.get("deviceId");
+
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ return;
+ }
+
+ try {
+ ProtocolDataMessageDTO protocolDataMessageDTO = protocolMessageAdapter.parseProtocolDataMessage(body);
+ // 构造 EncryptionDetails 对象
+ EncryptionDetailsDTO encryptionDetailsDTO = EncryptionDetailsDTO.builder()
+ .signKey(deviceCacheVO.getSignKey())
+ .encryptKey(deviceCacheVO.getEncryptKey())
+ .encryptVector(deviceCacheVO.getEncryptVector())
+ .build();
+ String dataBody = protocolMessageAdapter.decryptMessage(body, encryptionDetailsDTO);
+
+
+ // Parse body
+ TopoDeviceDataReportParam deviceDataParam = new TopoDeviceDataReportParam();
+ try {
+ deviceDataParam = JSON.toJavaObject(JSON.parseObject(dataBody), TopoDeviceDataReportParam.class);
+ } catch (Exception e) {
+ log.warn("The protocol format is incorrect");
+ return;
+ }
+ String resultDataBody = processingTopicMessage(deviceDataParam);
+
+ // Handle result
+ ProtocolDataMessageDTO handleResult = protocolMessageAdapter.buildResponse(protocolDataMessageDTO, resultDataBody, encryptionDetailsDTO);
+ String resultData = JSON.toJSONString(handleResult);
+
+ // Determine response topic based on request topic
+ String responseTopic = "/dataResponse";
+ // Generate response topic string
+ String responseTopicStr = generateResponseTopic(version, deviceId, responseTopic);
+
+ // Push message to MQTT to notify device of successful/failed data report
+ sendMessage(responseTopicStr, qos, resultData, String.valueOf(deviceCacheVO.getAppId()));
+ } catch (Exception e) {
+ log.error("Failed to decrypt the message", e);
+ }
+ }
+
+ /**
+ * Process /device/data Topic for device data reporting
+ *
+ * @param deviceDataParam device data
+ * @return Processing result json
+ */
+ @Override
+ protected String processingTopicMessage(Object deviceDataParam) throws Exception {
+ log.info("processingDeviceDataTopic Processing result:{}", JSON.toJSONString(deviceDataParam));
+ TopoDeviceDataReportParam dataReportParam = BeanPlusUtil.toBeanIgnoreError(deviceDataParam, TopoDeviceDataReportParam.class);
+ dataReportParam.getDevices().forEach(device -> {
+ log.info("processingDeviceDataTopic Processing result:{}", JSON.toJSONString(device));
+ String deviceId = device.getDeviceId();
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ log.warn("processingDeviceDataTopic Device not found:{}", deviceId);
+ return;
+ }
+ ProductModelCacheVO productModelCacheVO = getProductModelCacheVO(deviceCacheVO.getProductIdentification());
+ if (productModelCacheVO == null) {
+ log.warn("processingDeviceDataTopic Product Model not found:{}", deviceCacheVO.getProductIdentification());
+ return;
+ }
+
+ Map> dataMap = new HashMap<>();
+
+ device.getServices().forEach(service -> {
+ String superTableName = TdsUtils.superTableName(ProductTypeEnum.valueOf(deviceCacheVO.getProductCacheVO().getProductType()).getDesc(),
+ deviceCacheVO.getProductIdentification(),
+ service.getServiceCode());
+
+ String subTableName = TdsUtils.subTableName(superTableName, deviceCacheVO.getDeviceIdentification());
+
+ List productModelSuperTableCacheVO =
+ getProductModelSuperTableCacheVO(Optional.ofNullable(deviceCacheVO.getProductIdentification()).orElse(""),
+ service.getServiceCode(), deviceCacheVO.getDeviceIdentification());
+
+ //如果是空,需要做设备的初始化动作,并缓存模型表结构
+ if (CollUtil.isEmpty(productModelSuperTableCacheVO)) {
+ R> superTableDescribeVOListR = tdsApi.describeSuperOrSubTable(subTableName);
+
+ List existingFields = Optional.ofNullable(superTableDescribeVOListR.getData()).orElse(Collections.emptyList());
+
+ if (existingFields.isEmpty()) {
+ log.info("设备初始化,设备标识:{},服务标识:{}", deviceCacheVO.getDeviceIdentification(), service.getServiceCode());
+ TableDTO tableDTO = new TableDTO();
+ tableDTO.setSuperTableName(superTableName);
+ tableDTO.setTableName(subTableName);
+ List tagsFieldValues = new ArrayList<>();
+ Fields fields = new Fields();
+ fields.setFieldName(TdsConstants.DEVICE_IDENTIFICATION);
+ fields.setFieldValue(deviceCacheVO.getDeviceIdentification());
+ fields.setDataType(DataTypeEnum.BINARY);
+ tagsFieldValues.add(fields);
+ tableDTO.setTagsFieldValues(tagsFieldValues);
+ R subTable = tdsApi.createSubTable(tableDTO);
+ if (Boolean.TRUE.equals(subTable.getIsSuccess())) {
+ log.info("设备初始化,设备标识:{},服务标识:{},初始化成功", deviceCacheVO.getDeviceIdentification(), service.getServiceCode());
+ // 查询新的表结构信息存redis
+ setProductModelSuperTableCacheVO(Optional.ofNullable(deviceCacheVO.getProductIdentification()).orElse(""),
+ service.getServiceCode(), deviceCacheVO.getDeviceIdentification(), tdsApi.describeSuperOrSubTable(superTableName).getData());
+
+ } else {
+ log.warn("设备初始化 ,设备标识:{},服务标识:{},初始化失败", deviceCacheVO.getDeviceIdentification(), service.getServiceCode());
+ return;
+ }
+ } else {
+ setProductModelSuperTableCacheVO(Optional.ofNullable(deviceCacheVO.getProductIdentification()).orElse(""),
+ service.getServiceCode(), deviceCacheVO.getDeviceIdentification(), existingFields);
+ }
+
+ }
+
+ Long eventTime = Optional.ofNullable(service.getEventTime())
+ .map(Object::toString)
+ .flatMap(s -> {
+ try {
+ return Optional.of(Long.parseLong(s));
+ } catch (NumberFormatException e) {
+ return Optional.empty();
+ }
+ })
+ .orElse(System.currentTimeMillis());
+ List schemaFieldsList = new ArrayList<>();
+ List tagsFieldsList = new ArrayList<>();
+
+ Map data = StringUtils.jsonToMap(service.getData().toString());
+ dataMap.put(service.getServiceCode(), data);
+
+ productModelSuperTableCacheVO.forEach(superTableDescribeVO -> {
+ Fields fields = new Fields();
+ fields.setFieldName(superTableDescribeVO.getField());
+ DataTypeEnum dataTypeEnum = DataTypeEnum.valueOfByDataType(superTableDescribeVO.getType());
+ fields.setDataType(dataTypeEnum);
+ fields.setSize(superTableDescribeVO.getLength());
+
+ // 根据字段名称获取data里的数据
+ if (CollUtil.isNotEmpty(data) && data.containsKey(superTableDescribeVO.getField())) {
+ fields.setFieldValue(data.get(superTableDescribeVO.getField()));
+ } else if (TdsConstants.EVENT_TIME.equals(superTableDescribeVO.getField())) {
+ // 需要校验下是否为时间戳
+ fields.setFieldValue(eventTime);
+ } else if (TdsConstants.TS.equals(superTableDescribeVO.getField())) {
+ // 需要校验下是否为时间戳
+ fields.setFieldValue(DateUtils.millisecondStampL());
+ }
+
+ if (TdsConstants.TAG.equals(superTableDescribeVO.getNote())) {
+ if (!StringUtils.isEmpty(superTableDescribeVO.getField()) && TdsConstants.DEVICE_IDENTIFICATION.equals(superTableDescribeVO.getField())) {
+ fields.setFieldValue(deviceCacheVO.getDeviceIdentification());
+ }
+ tagsFieldsList.add(fields);
+ } else {
+ schemaFieldsList.add(fields);
+ }
+ });
+
+
+ //字段信息对象集合通过stream流过滤掉没有字段值的字段对象
+ List schemaFieldsStream = schemaFieldsList.stream().filter(fields -> fields.getFieldValue() != null).collect(Collectors.toList());
+ //字段信息对象集合通过stream流过滤掉没有字段值的字段对象
+ List tagsFieldsStream = tagsFieldsList.stream().filter(fields -> fields.getFieldValue() != null).collect(Collectors.toList());
+ //如果字段值只有第一个字段的时间戳,说明上报的数据没有符合该服务的属性,不做保存操作,跳过该循环,进入下个循环
+ if (CollUtil.isEmpty(schemaFieldsStream)) {
+ return;
+ }
+ //设置插入所需参数
+ TableDTO tableDTO = new TableDTO();
+ tableDTO.setSuperTableName(superTableName);
+ tableDTO.setTableName(subTableName);
+ tableDTO.setSchemaFieldValues(schemaFieldsStream);
+ tableDTO.setTagsFieldValues(tagsFieldsStream);
+
+ R insertedResult = tdsApi.insertTableData(tableDTO);
+
+ if (Boolean.TRUE.equals(insertedResult.getIsSuccess())) {
+ log.info("insert table data success, tableName:{}", subTableName);
+ } else {
+ log.error("insert table data failed, tableName:{}", subTableName);
+ }
+
+ });
+
+ ProductResultVO productResultVO = Optional.of(productModelCacheVO)
+ .map(item -> {
+ // 直接构建服务结果,如果productModelCacheVO为空,则会返回一个空列表
+ List serviceResultVOs = buildServiceResults(dataMap, productModelCacheVO);
+ // 复制属性并设置服务结果
+ ProductResultVO result = BeanPlusUtil.toBeanIgnoreError(productModelCacheVO, ProductResultVO.class);
+ result.setServices(serviceResultVOs);
+ return result;
+ })
+ .orElseGet(() -> {
+ // 只有当deviceCacheVO为null或者没有找到ProductModelCacheVO时,才会返回一个新的ProductResultVO实例
+ ProductResultVO emptyResult = new ProductResultVO();
+ emptyResult.setServices(Collections.emptyList());
+ return emptyResult;
+ });
+
+ log.info("productResultVO: {}", JSON.toJSONString(productResultVO));
+ setDeviceDataCollectionPoolCacheVO(Optional.ofNullable(deviceCacheVO.getProductIdentification()).orElse(""),
+ deviceCacheVO.getDeviceIdentification(), productResultVO);
+ });
+
+ return JSON.toJSONString("");
+ }
+
+ private List buildServiceResults(Map> dataMap, ProductModelCacheVO productModelCacheVO) {
+ // Check if the productModelCacheVO is null or if getServices() returns null to avoid NullPointerException.
+ if (productModelCacheVO == null || productModelCacheVO.getServices() == null) {
+ return Collections.emptyList(); // Return an empty list if there are no services.
+ }
+
+ // If dataMap is null, replace it with an empty map to avoid NullPointerException when calling get().
+ Map> safeDataMap = (dataMap != null) ? dataMap : Collections.emptyMap();
+
+ return productModelCacheVO.getServices().stream()
+ .map(productServiceParamVO -> {
+ // Use the safeDataMap for getting the service data, handle potential null value from the map.
+ Map serviceData = safeDataMap.getOrDefault(productServiceParamVO.getServiceCode(), Collections.emptyMap());
+
+ // Build the property results, which also handles nulls inside the method.
+ List propertyResultVOs = buildPropertyResults(productServiceParamVO, serviceData);
+
+ // Convert the service parameter object into a result object and set the properties.
+ ProductServiceResultVO serviceResultVO = BeanPlusUtil.toBeanIgnoreError(productServiceParamVO, ProductServiceResultVO.class);
+ serviceResultVO.setProperties(propertyResultVOs); // This will include the property results, even if empty.
+
+ return serviceResultVO;
+ })
+ .collect(Collectors.toList());
+ }
+
+
+ private List buildPropertyResults(ProductServiceParamVO productServiceParamVO, Map dataList) {
+ // Check if the provided dataList is null and return an empty list if so
+ if (dataList == null) {
+ return Collections.emptyList();
+ }
+
+ // Now proceed as before, since we're sure dataList is not null
+ return productServiceParamVO.getProperties().stream()
+ .map(productPropertyParamVO -> {
+ String propertyCode = productPropertyParamVO.getPropertyCode();
+ // Directly check if dataList contains the property code
+ if (dataList.containsKey(propertyCode)) {
+ ProductPropertyResultVO propertyResultVO = BeanPlusUtil.toBeanIgnoreError(productPropertyParamVO, ProductPropertyResultVO.class);
+ propertyResultVO.setPropertyValue(dataList.get(propertyCode));
+ return propertyResultVO;
+ } else {
+ // If a property is not present, you might choose to skip it or return a default instance
+ // For example, you can return an instance with null for the property value, or you can simply return null to filter it out later
+ // This example will skip the missing properties
+ return null;
+ }
+ })
+ .filter(Objects::nonNull) // Filter out any nulls if the property code was not present in dataList
+ .collect(Collectors.toList());
+ }
+
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/OtaCommandResponseHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/OtaCommandResponseHandler.java
new file mode 100644
index 00000000..67015df9
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/OtaCommandResponseHandler.java
@@ -0,0 +1,88 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventOtaCommandResponseService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 处理OTA_COMMAND_RESPONSE主题
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2024-01-15 23:00
+ **/
+@Slf4j
+@Service
+public class OtaCommandResponseHandler extends AbstractMessageHandler implements TopicHandler {
+ public OtaCommandResponseHandler(CacheDataHelper cacheDataHelper,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ }
+
+ @Autowired
+ private MqttEventOtaCommandResponseService mqttEventOtaCommandResponseService;
+
+ /**
+ * Handles MQTT messages, decrypts them, and processes the command.
+ *
+ * @param topic The topic the message was published to.
+ * @param qos The Quality of Service level of the message.
+ * @param body The raw body of the MQTT message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ if (!protocolMessageAdapter.validateProtocolData(body)) {
+ log.warn("The protocol format is incorrect");
+ return;
+ }
+
+ Map variables = protocolMessageAdapter.extractVariables(topic);
+ String deviceId = variables.get("deviceId");
+
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ log.warn("Device with ID {} not found.", deviceId);
+ return;
+ }
+
+ try {
+ EncryptionDetailsDTO encryptionDetailsDTO = EncryptionDetailsDTO.builder()
+ .signKey(deviceCacheVO.getSignKey())
+ .encryptKey(deviceCacheVO.getEncryptKey())
+ .encryptVector(deviceCacheVO.getEncryptVector())
+ .build();
+ String decryptedBody = protocolMessageAdapter.decryptMessage(body, encryptionDetailsDTO);
+ mqttEventOtaCommandResponseService.saveMqttEventOtaCommandResponse(deviceCacheVO, decryptedBody);
+ } catch (Exception e) {
+ log.error("Failed to decrypt the message", e);
+ }
+ }
+
+
+ /**
+ * Processes the message and returns the response body.
+ *
+ * @param messageParam The message body.
+ * @return The response body.
+ * @throws Exception If an error occurs while processing the message.
+ */
+ @Override
+ protected String processingTopicMessage(Object messageParam) throws Exception {
+
+ return null;
+ }
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/QueryDeviceHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/QueryDeviceHandler.java
new file mode 100644
index 00000000..a53f457b
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/QueryDeviceHandler.java
@@ -0,0 +1,116 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.basic.protocol.model.ProtocolDataMessageDTO;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoQueryDeviceParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 处理QUERY_DEVICE主题
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2024-01-10 11:59
+ **/
+@Slf4j
+@Service
+public class QueryDeviceHandler extends AbstractMessageHandler implements TopicHandler {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ public QueryDeviceHandler(CacheDataHelper cacheDataHelper,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ }
+
+ /**
+ * @param topic the MQTT topic the message was received on.
+ * @param qos the quality of service level of the message.
+ * @param body the payload of the message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ if (!protocolMessageAdapter.validateProtocolData(body)) {
+ log.warn("The protocol format is incorrect");
+ return;
+ }
+ // 解析Topic
+ Map stringStringMap = protocolMessageAdapter.extractVariables(topic);
+ String version = stringStringMap.get("version");
+ String deviceId = stringStringMap.get("deviceId");
+
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ return;
+ }
+
+ try {
+ ProtocolDataMessageDTO protocolDataMessageDTO = protocolMessageAdapter.parseProtocolDataMessage(body);
+ // 构造 EncryptionDetails 对象
+ EncryptionDetailsDTO encryptionDetailsDTO = EncryptionDetailsDTO.builder()
+ .signKey(deviceCacheVO.getSignKey())
+ .encryptKey(deviceCacheVO.getEncryptKey())
+ .encryptVector(deviceCacheVO.getEncryptVector())
+ .build();
+ String dataBody = protocolMessageAdapter.decryptMessage(body, encryptionDetailsDTO);
+
+ // 解析body
+ TopoQueryDeviceParam topoQueryDeviceParam = JSON.toJavaObject(JSON.parseObject(dataBody), TopoQueryDeviceParam.class);
+ String resultDataBody = processingTopicMessage(topoQueryDeviceParam);
+
+ // 处理返回结果
+ ProtocolDataMessageDTO handleResult = protocolMessageAdapter.buildResponse(protocolDataMessageDTO, resultDataBody, encryptionDetailsDTO);
+
+ // 根据请求主题确定响应主题
+ String responseTopic = "/topo/queryResponse";
+ // 生成响应主题字符串
+ String responseTopicStr = generateResponseTopic(version, deviceId, responseTopic);
+
+ // 序列化 handleResult 对象为 JSON 字符串
+ String resultData = objectMapper.writeValueAsString(handleResult);
+
+ // 推送消息到 MQTT 通知设备添加子设备成功&失败
+ sendMessage(responseTopicStr, qos, resultData, String.valueOf(deviceCacheVO.getAppId()));
+ } catch (Exception e) {
+ log.error("Failed to decrypt the message", e);
+ }
+ }
+
+ /**
+ * Processes the message received on the /topo/query Topic to query device information.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return The JSON representation of the query result.
+ * @throws Exception if there is an issue processing the message.
+ */
+ @Override
+ protected String processingTopicMessage(Object topoQueryDeviceParam) throws Exception {
+ if (!(topoQueryDeviceParam instanceof TopoQueryDeviceParam)) {
+ throw new IllegalArgumentException("Invalid parameter type for device query");
+ }
+
+ TopoQueryDeviceParam queryParam = (TopoQueryDeviceParam) topoQueryDeviceParam;
+ R topoQueryDeviceResultVOR = remoteDeviceService.queryDeviceByMqtt(queryParam);
+
+ log.info("Processing /topo/query result: {}", JSON.toJSONString(topoQueryDeviceResultVOR));
+ return JSON.toJSONString(topoQueryDeviceResultVOR.getData());
+ }
+
+
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/SecretKeyHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/SecretKeyHandler.java
new file mode 100644
index 00000000..5408ad73
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/SecretKeyHandler.java
@@ -0,0 +1,86 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 处理SECRET_KEY主题
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 22:57
+ **/
+@Slf4j
+@Service
+public class SecretKeyHandler extends AbstractMessageHandler implements TopicHandler {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ public SecretKeyHandler(CacheDataHelper cacheDataHelper,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ }
+
+ /**
+ * @param topic the MQTT topic the message was received on.
+ * @param qos the quality of service level of the message.
+ * @param body the payload of the message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ // Extract variables from the topic
+ Map stringStringMap = protocolMessageAdapter.extractVariables(topic);
+ String version = stringStringMap.get("version");
+ String deviceId = stringStringMap.get("deviceId");
+
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ return;
+ }
+
+ try {
+ // Directly parse the body into SecretKeyParam class
+ /*SecretKeyParam secretKeyParam = JSON.toJavaObject(JSON.parseObject(body), SecretKeyParam.class);
+ secretKeyParam.setDeviceIdentification(deviceId);
+ String resultDataBody = processingTopicMessage(secretKeyParam);*/
+
+ // Determine response topic based on request topic
+ String responseTopic = "/secret/keyResponse";
+ // Generate response topic string
+ String responseTopicStr = generateResponseTopic(version, deviceId, responseTopic);
+
+ // Push message to MQTT to notify device of successful/failed secret key retrieval
+ sendMessage(responseTopicStr, qos, "", String.valueOf(deviceCacheVO.getAppId()));
+ } catch (Exception e) {
+ log.error("Failed to parse the message", e);
+ }
+ }
+
+ /**
+ * Process /secret/key Topic for secret key retrieval
+ *
+ * @param secretKeyParam secret key data
+ * @return Processing result json
+ */
+ @Override
+ protected String processingTopicMessage(Object secretKeyParam) throws Exception {
+ // Call the API to retrieve the secret key
+// R mqttSecretKeyResultVOR = deviceOpenAnyTenantApi.getSecretKeyByMqtt((SecretKeyParam) secretKeyParam);
+ log.info("processingSecretKeyTopic Processing result:{}", JSON.toJSONString(secretKeyParam));
+ return JSON.toJSONString("");
+ }
+}
+
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/TopicHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/TopicHandler.java
new file mode 100644
index 00000000..09c460f2
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/TopicHandler.java
@@ -0,0 +1,19 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description:
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 22:45
+ **/
+public interface TopicHandler {
+
+ /**
+ * @param topic the MQTT topic the message was received on.
+ * @param qos the quality of service level of the message.
+ * @param body the payload of the message.
+ */
+ void handle(String topic, String qos, String body);
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/UpdateSubDeviceHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/UpdateSubDeviceHandler.java
new file mode 100644
index 00000000..1dd8f0be
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/UpdateSubDeviceHandler.java
@@ -0,0 +1,109 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.basic.protocol.model.ProtocolDataMessageDTO;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoUpdateSubDeviceStatusParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 处理UPDATE_SUB_DEVICE主题
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 23:00
+ **/
+@Slf4j
+@Service
+public class UpdateSubDeviceHandler extends AbstractMessageHandler implements TopicHandler {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ public UpdateSubDeviceHandler(CacheDataHelper cacheDataHelper,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ }
+
+ /**
+ * @param topic the MQTT topic the message was received on.
+ * @param qos the quality of service level of the message.
+ * @param body the payload of the message.
+ */
+ @Override
+ public void handle(String topic, String qos, String body) {
+ if (!protocolMessageAdapter.validateProtocolData(body)) {
+ log.warn("The protocol format is incorrect");
+ return;
+ }
+
+ // Extract variables from the topic
+ Map stringStringMap = protocolMessageAdapter.extractVariables(topic);
+ String version = stringStringMap.get("version");
+ String deviceId = stringStringMap.get("deviceId");
+
+ DeviceCacheVO deviceCacheVO = getDeviceCacheVO(deviceId);
+ if (deviceCacheVO == null) {
+ return;
+ }
+
+ try {
+ ProtocolDataMessageDTO protocolDataMessageDTO = protocolMessageAdapter.parseProtocolDataMessage(body);
+ // 构造 EncryptionDetails 对象
+ EncryptionDetailsDTO encryptionDetailsDTO = EncryptionDetailsDTO.builder()
+ .signKey(deviceCacheVO.getSignKey())
+ .encryptKey(deviceCacheVO.getEncryptKey())
+ .encryptVector(deviceCacheVO.getEncryptVector())
+ .build();
+ String dataBody = protocolMessageAdapter.decryptMessage(body, encryptionDetailsDTO);
+
+ // Parse body
+ TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam = JSON.toJavaObject(JSON.parseObject(dataBody), TopoUpdateSubDeviceStatusParam.class);
+ topoUpdateSubDeviceStatusParam.setGatewayIdentification(deviceId);
+ String resultDataBody = processingTopicMessage(topoUpdateSubDeviceStatusParam);
+
+ // Handle result
+ ProtocolDataMessageDTO handleResult = protocolMessageAdapter.buildResponse(protocolDataMessageDTO, resultDataBody, encryptionDetailsDTO);
+
+ // Determine response topic based on request topic
+ String responseTopic = "/topo/updateResponse";
+ // Generate response topic string
+ String responseTopicStr = generateResponseTopic(version, deviceId, responseTopic);
+
+ // 序列化 handleResult 对象为 JSON 字符串
+ String resultData = objectMapper.writeValueAsString(handleResult);
+ // Push message to MQTT to notify device of successful/failed sub-device update
+ sendMessage(responseTopicStr, qos, resultData, String.valueOf(deviceCacheVO.getAppId()));
+ } catch (Exception e) {
+ log.error("Failed to decrypt the message", e);
+ }
+ }
+
+ /**
+ * Process /topo/update Topic for gateway device to update sub-device
+ *
+ * @param topoUpdateSubDeviceParam update device data
+ * @return Processing result json
+ */
+ @Override
+ protected String processingTopicMessage(Object topoUpdateSubDeviceParam) throws Exception {
+ R topoDeviceOperationResultVOR =
+ remoteDeviceService.updateSubDeviceConnectStatusByMqtt((TopoUpdateSubDeviceStatusParam) topoUpdateSubDeviceParam);
+ log.info("processingTopoUpdateTopic Processing result:{}", JSON.toJSONString(topoDeviceOperationResultVOR));
+ return JSON.toJSONString(topoDeviceOperationResultVOR.getData());
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/event/MqttMessageEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/event/MqttMessageEvent.java
new file mode 100644
index 00000000..77c5bba0
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/event/MqttMessageEvent.java
@@ -0,0 +1,91 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.event;
+
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MessageEvent
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handle.event
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 14:42
+ **/
+public class MqttMessageEvent extends ApplicationEvent {
+ private final String topic;
+ private final String qos;
+ private final String message;
+ private final String time;
+
+ public MqttMessageEvent(Object source, String topic, String qos, String message, String time) {
+ super(source);
+ this.topic = topic;
+ this.qos = qos;
+ this.message = message;
+ this.time = time;
+ }
+
+ public String getTopic() {
+ return topic;
+ }
+
+ public String getQos() {
+ return qos;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getTime() {
+ return time;
+ }
+
+
+ public class AddSubDeviceEvent extends MqttMessageEvent {
+ public AddSubDeviceEvent(Object source, String topic, String qos, String body, String time) {
+ super(source, topic, qos, body, time);
+ }
+ }
+
+ public class AddSubDeviceResponseEvent extends MqttMessageEvent {
+ public AddSubDeviceResponseEvent(Object source, String topic, String qos, String body, String time) {
+ super(source, topic, qos, body, time);
+ }
+ }
+
+ public class DeviceStatusEvent extends MqttMessageEvent {
+ public DeviceStatusEvent(Object source, String topic, String qos, String body, String time) {
+ super(source, topic, qos, body, time);
+ }
+ }
+
+ public class DeviceStatusResponseEvent extends MqttMessageEvent {
+ public DeviceStatusResponseEvent(Object source, String topic, String qos, String body, String time) {
+ super(source, topic, qos, body, time);
+ }
+ }
+
+ public class DeviceControlEvent extends MqttMessageEvent {
+ public DeviceControlEvent(Object source, String topic, String qos, String body, String time) {
+ super(source, topic, qos, body, time);
+ }
+ }
+
+ public class DeviceControlResponseEvent extends MqttMessageEvent {
+ public DeviceControlResponseEvent(Object source, String topic, String qos, String body, String time) {
+ super(source, topic, qos, body, time);
+ }
+ }
+
+ public class DeviceDataReportEvent extends MqttMessageEvent {
+ public DeviceDataReportEvent(Object source, String topic, String qos, String body, String time) {
+ super(source, topic, qos, body, time);
+ }
+ }
+
+ public class DeviceDataReportResponseEvent extends MqttMessageEvent {
+ public DeviceDataReportResponseEvent(Object source, String topic, String qos, String body, String time) {
+ super(source, topic, qos, body, time);
+ }
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/AbstractMessageHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/AbstractMessageHandler.java
new file mode 100644
index 00000000..51fab2bb
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/AbstractMessageHandler.java
@@ -0,0 +1,85 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory;
+
+
+import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.broker.api.domain.vo.PublishMessageRequestVO;
+import com.mqttsnet.thinglinks.common.core.utils.SnowflakeIdUtil;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductModelCacheVO;
+import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDescribeVO;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: 通用逻辑处理器
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-30 15:07
+ **/
+@Slf4j
+public abstract class AbstractMessageHandler {
+
+ protected final CacheDataHelper cacheDataHelper;
+ protected final RemoteDeviceService remoteDeviceService;
+ protected final RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi;
+ protected final ProtocolMessageAdapter protocolMessageAdapter;
+
+ public AbstractMessageHandler(CacheDataHelper cacheDataHelper,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ this.cacheDataHelper = cacheDataHelper;
+ this.remoteDeviceService = remoteDeviceService;
+ this.remoteMqttBrokerOpenApi = remoteMqttBrokerOpenApi;
+ this.protocolMessageAdapter = protocolMessageAdapter;
+ }
+
+ protected DeviceCacheVO getDeviceCacheVO(String deviceIdentification) {
+ return cacheDataHelper.getDeviceCacheVO(deviceIdentification);
+ }
+
+ protected ProductModelCacheVO getProductModelCacheVO(String productIdentification) {
+ return cacheDataHelper.getProductModelCacheVO(productIdentification);
+ }
+
+ protected List getProductModelSuperTableCacheVO(String productIdentification, String serviceCode, String deviceIdentification) {
+ return cacheDataHelper.getProductModelSuperTableCacheVO(productIdentification, serviceCode, deviceIdentification);
+ }
+
+ protected void setProductModelSuperTableCacheVO(String productIdentification, String serviceCode, String deviceIdentification,
+ List superTableDescribeOpt) {
+ cacheDataHelper.setProductModelSuperTableCacheVO(productIdentification, serviceCode, deviceIdentification, superTableDescribeOpt);
+ }
+
+ protected void sendMessage(String topic, String qos, String message, String tenantId) {
+ PublishMessageRequestVO publishMessageRequestVO = new PublishMessageRequestVO();
+ publishMessageRequestVO.setReqId(Long.valueOf(SnowflakeIdUtil.nextId()));
+ publishMessageRequestVO.setTenantId(tenantId);
+ publishMessageRequestVO.setTopic(topic);
+ publishMessageRequestVO.setPubQos(qos);
+ publishMessageRequestVO.setClientType("web");
+ publishMessageRequestVO.setPayload(message);
+ publishMessageRequestVO.setRetain("false");
+ remoteMqttBrokerOpenApi.sendMessage(publishMessageRequestVO);
+ }
+
+ /**
+ * 生成响应主题字符串
+ *
+ * @param version 版本号
+ * @param deviceId 设备ID
+ * @param responseTopic 响应主题
+ * @return 完整的响应主题字符串
+ */
+ protected String generateResponseTopic(String version, String deviceId, String responseTopic) {
+ return String.format("/%s/devices/%s%s", version, deviceId, responseTopic);
+ }
+
+ protected abstract String processingTopicMessage(Object messageParam) throws Exception;
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/TopicHandlerFactory.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/TopicHandlerFactory.java
new file mode 100644
index 00000000..a5fc13c4
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/TopicHandlerFactory.java
@@ -0,0 +1,106 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory;
+
+
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.*;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MQTT系统Topic 处理工厂类
+ * @packagename: com.mqttsnet.thinglinks.handler.factory
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-05 22:00
+ **/
+@Component
+public class TopicHandlerFactory {
+
+ private final DefaultHandler defaultHandler;
+ private final SecretKeyHandler secretKeyHandler;
+ private final AddSubDeviceHandler addSubDeviceHandler;
+ private final DeleteSubDeviceHandler deleteSubDeviceHandler;
+ private final UpdateSubDeviceHandler updateSubDeviceHandler;
+ private final QueryDeviceHandler queryDeviceHandler;
+ private final DeviceDatasHandler deviceDatasHandler;
+ private final CommandResponseHandler commandResponseHandler;
+
+ private final OtaCommandResponseHandler otaCommandResponseHandler;
+
+ // Define patterns as constants
+ private static final Pattern DEFAULT_PATTERN = Pattern.compile("");
+ private static final Pattern SECRET_KEY_PATTERN = Pattern.compile("/([^/]+)/devices/([^/]+)/topo/secretKey");
+ private static final Pattern ADD_SUB_DEVICE_PATTERN = Pattern.compile("/([^/]+)/devices/([^/]+)/topo/add");
+ private static final Pattern DELETE_SUB_DEVICE_PATTERN = Pattern.compile("/([^/]+)/devices/([^/]+)/topo/delete");
+ private static final Pattern UPDATE_SUB_DEVICE_PATTERN = Pattern.compile("/([^/]+)/devices/([^/]+)/topo/update");
+ private static final Pattern QUERY_DEVICE_PATTERN = Pattern.compile("/([^/]+)/devices/([^/]+)/topo/query");
+ private static final Pattern DEVICE_DATAS_PATTERN = Pattern.compile("/([^/]+)/devices/([^/]+)/datas");
+ private static final Pattern COMMAND_RESPONSE_PATTERN = Pattern.compile("/([^/]+)/devices/([^/]+)/commandResponse");
+ private static final Pattern OTA_COMMAND_RESPONSE_PATTERN = Pattern.compile("/([^/]+)/devices/([^/]+)/otaCommandResponse");
+
+ public TopicHandlerFactory(DefaultHandler defaultHandler, SecretKeyHandler secretKeyHandler,
+ AddSubDeviceHandler addSubDeviceHandler, DeleteSubDeviceHandler deleteSubDeviceHandler,
+ UpdateSubDeviceHandler updateSubDeviceHandler, QueryDeviceHandler queryDeviceHandler, DeviceDatasHandler deviceDatasHandler,
+ CommandResponseHandler commandResponseHandler, OtaCommandResponseHandler otaCommandResponseHandler) {
+ this.defaultHandler = defaultHandler;
+ this.secretKeyHandler = secretKeyHandler;
+ this.addSubDeviceHandler = addSubDeviceHandler;
+ this.deleteSubDeviceHandler = deleteSubDeviceHandler;
+ this.updateSubDeviceHandler = updateSubDeviceHandler;
+ this.queryDeviceHandler = queryDeviceHandler;
+ this.deviceDatasHandler = deviceDatasHandler;
+ this.commandResponseHandler = commandResponseHandler;
+ this.otaCommandResponseHandler = otaCommandResponseHandler;
+ }
+
+ private static final class TopicHandlerEntry {
+ private final Pattern pattern;
+ private final TopicHandler handler;
+
+ public TopicHandlerEntry(Pattern pattern, TopicHandler handler) {
+ this.pattern = pattern;
+ this.handler = handler;
+ }
+
+ public Pattern getPattern() {
+ return pattern;
+ }
+
+ public TopicHandler getHandler() {
+ return handler;
+ }
+ }
+
+ private List topicHandlerEntries;
+
+ // Use the @PostConstruct annotation to initialize the handler entries list after the dependencies are injected.
+ @PostConstruct
+ public void initTopicHandlerEntries() {
+ topicHandlerEntries = new ArrayList<>();
+ topicHandlerEntries.add(new TopicHandlerEntry(DEFAULT_PATTERN, defaultHandler));
+ topicHandlerEntries.add(new TopicHandlerEntry(SECRET_KEY_PATTERN, secretKeyHandler));
+ topicHandlerEntries.add(new TopicHandlerEntry(ADD_SUB_DEVICE_PATTERN, addSubDeviceHandler));
+ topicHandlerEntries.add(new TopicHandlerEntry(DELETE_SUB_DEVICE_PATTERN, deleteSubDeviceHandler));
+ topicHandlerEntries.add(new TopicHandlerEntry(UPDATE_SUB_DEVICE_PATTERN, updateSubDeviceHandler));
+ topicHandlerEntries.add(new TopicHandlerEntry(QUERY_DEVICE_PATTERN, queryDeviceHandler));
+ topicHandlerEntries.add(new TopicHandlerEntry(DEVICE_DATAS_PATTERN, deviceDatasHandler));
+ topicHandlerEntries.add(new TopicHandlerEntry(COMMAND_RESPONSE_PATTERN, commandResponseHandler));
+ topicHandlerEntries.add(new TopicHandlerEntry(OTA_COMMAND_RESPONSE_PATTERN, otaCommandResponseHandler));
+ }
+
+ // This method searches for a matching handler based on the topic.
+ public TopicHandler findMatchingHandler(String topic) {
+ for (TopicHandlerEntry handlerEntry : topicHandlerEntries) {
+ Matcher matcher = handlerEntry.getPattern().matcher(topic);
+ if (matcher.matches()) {
+ return handlerEntry.getHandler();
+ }
+ }
+ return defaultHandler;
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/listener/MqttMessageListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/listener/MqttMessageListener.java
new file mode 100644
index 00000000..47a03a38
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/listener/MqttMessageListener.java
@@ -0,0 +1,48 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.listener;
+
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.TopicHandler;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.event.MqttMessageEvent;
+import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.TopicHandlerFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description:
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handle.listener
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-04-28 14:43
+ **/
+@Component
+@Slf4j
+public class MqttMessageListener {
+
+ private final TopicHandlerFactory topicHandlerFactory;
+
+ @Autowired
+ public MqttMessageListener(TopicHandlerFactory topicHandlerFactory) {
+ this.topicHandlerFactory = topicHandlerFactory;
+ }
+
+ @EventListener
+ public void handleMessage(MqttMessageEvent event) {
+ // 校验并处理Topic
+ processTopic(event.getTopic(), event.getQos(), event.getMessage());
+ }
+
+ private void processTopic(String topic, String qos, String body) {
+ // Using the TopicHandlerFactory to find the matching handler
+ TopicHandler matchingHandler = topicHandlerFactory.findMatchingHandler(topic);
+
+ if (matchingHandler != null) {
+ matchingHandler.handle(topic, qos, body);
+ } else {
+ // Handle the case when no topic matches
+ log.warn("No topic handler found for topic: {}", topic);
+ }
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventActionService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventActionService.java
new file mode 100644
index 00000000..00073186
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventActionService.java
@@ -0,0 +1,60 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.service;
+
+import com.google.gson.Gson;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceActionService;
+import com.mqttsnet.thinglinks.link.api.domain.device.entity.DeviceAction;
+import com.mqttsnet.thinglinks.link.api.domain.device.enumeration.DeviceActionTypeEnum;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MqttEventActionHandler
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-08-20 16:09
+ **/
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class MqttEventActionService {
+
+ @Resource
+ private RemoteDeviceActionService remoteDeviceActionService;
+
+ /**
+ * 保存MQTT事件动作
+ *
+ * @param eventMessage 事件消息
+ * @param actionType 动作类型
+ * @param describable 描述
+ */
+ public void saveMqttEventAction(String eventMessage, DeviceActionTypeEnum actionType, String describable) {
+ Gson gson = new Gson();
+ Map map = new HashMap<>();
+ map = gson.fromJson(eventMessage, map.getClass());
+ String clientId = String.valueOf(map.get("clientId"));
+
+ // save device action
+ DeviceAction deviceAction = new DeviceAction()
+ .setDeviceIdentification(clientId)
+ .setActionType(actionType.getAction())
+ .setStatus(ResultEnum.SUCCESS.getMessage())
+ .setMessage(describable);
+
+ R deviceActionR = remoteDeviceActionService.add(deviceAction);
+ if (ResultEnum.SUCCESS.getCode() != deviceActionR.getCode()) {
+ log.info("Save device action success: deviceAction={}", deviceActionR.getData());
+ } else {
+ log.error("Save device action failed: deviceAction={}", deviceActionR.getData());
+ }
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventCommandService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventCommandService.java
new file mode 100644
index 00000000..21e2a06d
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventCommandService.java
@@ -0,0 +1,62 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.service;
+
+import com.alibaba.fastjson.JSON;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @program: thinglinks-cloud-pro-datasource-column
+ * @description: MqttEventCommandService
+ * @packagename: com.mqttsnet.thinglinks.mqtt.handler
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-11-12 16:09
+ **/
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class MqttEventCommandService {
+
+ private final DeviceCommandApi deviceCommandApi;
+
+ /**
+ * Processes the received message, converts it to a DeviceCommandSaveVO, and saves the command.
+ *
+ * @param deviceCacheVO The cached device information.
+ * @param dataBody The body of the MQTT message.
+ * @return A JSON string representing the saved device command.
+ */
+ public String processCommand(DeviceCacheVO deviceCacheVO, String dataBody) {
+ DeviceCommandSaveVO saveVO = convertToSaveVO(deviceCacheVO, dataBody);
+ R response = deviceCommandApi.saveDeviceCommand(saveVO);
+
+ if (Boolean.FALSE.equals(response.getIsSuccess())) {
+ log.error("Failed to process device command: {}", JSON.toJSONString(response));
+ throw new IllegalStateException("Failed to save device command");
+ }
+
+ log.info("Device command processed and saved: {}", JSON.toJSONString(response.getData()));
+ return JSON.toJSONString(response.getData());
+ }
+
+ /**
+ * Converts the received message body to a DeviceCommandSaveVO object.
+ *
+ * @param deviceCacheVO The cached device information.
+ * @param dataBody The body of the MQTT message.
+ * @return The DeviceCommandSaveVO object.
+ */
+ private DeviceCommandSaveVO convertToSaveVO(DeviceCacheVO deviceCacheVO, String dataBody) {
+ // Your conversion logic here
+ // For now, creating a new object with some default values
+ DeviceCommandSaveVO saveVO = new DeviceCommandSaveVO();
+ saveVO.setDeviceIdentification(deviceCacheVO.getDeviceIdentification());
+ saveVO.setCommandType(DeviceCommandTypeEnum.COMMAND_RESPONSE.getValue());
+ saveVO.setStatus(DeviceCommandStatusEnum.SUCCESS.getValue());
+ saveVO.setContent(dataBody);
+ saveVO.setRemark("Processed command response");
+ return saveVO;
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventOtaCommandResponseService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventOtaCommandResponseService.java
new file mode 100644
index 00000000..052e8083
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventOtaCommandResponseService.java
@@ -0,0 +1,75 @@
+package com.mqttsnet.thinglinks.broker.mqs.mqtt.service;
+
+import com.alibaba.fastjson.JSON;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.OtaCommandResponseParam;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: MqttEventOtaCommandResponseService
+ * -----------------------------------------------------------------------------
+ * Description:
+ * OTA 远程升级 mqtt事件业务层
+ * -----------------------------------------------------------------------------
+ *
+ * @author xiaonannet
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ * 2024/1/18 xiaonannet 1.0 Initial creation
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2024/1/18 22:38
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class MqttEventOtaCommandResponseService {
+
+ @Autowired
+ private RemoteDeviceService remoteDeviceService;
+
+
+ /**
+ * Saves the OTA command response from MQTT events.
+ *
+ * @param deviceCacheVO Device cache information for the device receiving the OTA command.
+ * @param dataBody The message body containing the OTA command response.
+ */
+ public void saveMqttEventOtaCommandResponse(DeviceCacheVO deviceCacheVO, String dataBody) {
+ try {
+ // Convert the JSON data body to an OtaCommandResponseParam object
+ OtaCommandResponseParam otaCommandResponseParam = JSON.parseObject(dataBody, OtaCommandResponseParam.class);
+
+ // Assuming a method that handles the actual saving of the response
+ saveOtaCommandResponse(otaCommandResponseParam);
+
+ // Log the successfully saved command response
+ log.info("OTA command response successfully saved: {}", JSON.toJSONString(otaCommandResponseParam));
+
+ } catch (Exception e) {
+ // Log the error along with the stack trace for debugging
+ log.error("Failed to process OTA command response: {}", dataBody, e);
+
+ // Re-throw the exception to maintain the flow (can be customized as needed)
+ throw new IllegalStateException("Failed to save OTA command response", e);
+ }
+ }
+
+ // This is a placeholder for the actual saving logic
+ private void saveOtaCommandResponse(OtaCommandResponseParam responseParam) {
+ // Implementation for saving the response in your system
+ R otaCommandResponseParamR = remoteDeviceService.saveUpgradeRecordByMqtt(responseParam);
+ log.info("otaCommandResponseParamR:{}", JSON.toJSONString(otaCommandResponseParamR));
+ }
+
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/MqttBrokerService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/MqttBrokerService.java
index 1f15eae9..edee825b 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/MqttBrokerService.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/MqttBrokerService.java
@@ -1,6 +1,6 @@
package com.mqttsnet.thinglinks.broker.service;
-import com.mqttsnet.thinglinks.broker.api.domain.model.PublishMessageRequest;
+import com.mqttsnet.thinglinks.broker.api.domain.vo.PublishMessageRequestVO;
import com.mqttsnet.thinglinks.common.core.exception.base.BaseException;
/**
@@ -28,9 +28,9 @@ public interface MqttBrokerService {
/**
* Publishes a message to a specified topic and returns the content if successful.
*
- * @param publishMessageRequest Object containing the required parameters for publishing.
+ * @param publishMessageRequestVO Object containing the required parameters for publishing.
* @return The content of the published message.
* @throws BaseException If the publishing fails.
*/
- String publishMessage(PublishMessageRequest publishMessageRequest);
+ String publishMessage(PublishMessageRequestVO publishMessageRequestVO);
}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/impl/MqttBrokerServiceImpl.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/impl/MqttBrokerServiceImpl.java
index 391b6442..bc9d4f91 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/impl/MqttBrokerServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/service/impl/MqttBrokerServiceImpl.java
@@ -1,7 +1,7 @@
package com.mqttsnet.thinglinks.broker.service.impl;
import com.mqttsnet.thinglinks.broker.api.BifroMQApi;
-import com.mqttsnet.thinglinks.broker.api.domain.model.PublishMessageRequest;
+import com.mqttsnet.thinglinks.broker.api.domain.vo.PublishMessageRequestVO;
import com.mqttsnet.thinglinks.broker.service.MqttBrokerService;
import com.mqttsnet.thinglinks.common.core.exception.base.BaseException;
import lombok.RequiredArgsConstructor;
@@ -39,23 +39,23 @@ public class MqttBrokerServiceImpl implements MqttBrokerService {
/**
* Publishes a message to a specified topic and returns the content if successful.
*
- * @param publishMessageRequest Object containing the required parameters for publishing.
+ * @param publishMessageRequestVO Object containing the required parameters for publishing.
* @return The content of the published message.
* @throws BaseException If the publishing fails.
*/
@Override
- public String publishMessage(PublishMessageRequest publishMessageRequest) throws BaseException {
- log.info("Preparing to publish message with topic: {}", publishMessageRequest.getTopic());
+ public String publishMessage(PublishMessageRequestVO publishMessageRequestVO) throws BaseException {
+ log.info("Preparing to publish message with topic: {}", publishMessageRequestVO.getTopic());
try {
- ResponseEntity response = callPublishApi(publishMessageRequest);
+ ResponseEntity response = callPublishApi(publishMessageRequestVO);
if (response.getStatusCode().is2xxSuccessful()) {
- log.info("Successfully published message with topic: {}", publishMessageRequest.getTopic());
- return publishMessageRequest.getPayload(); // Return the message content that was published
+ log.info("Successfully published message with topic: {}", publishMessageRequestVO.getTopic());
+ return publishMessageRequestVO.getPayload(); // Return the message content that was published
} else {
log.error("Failed to publish message with topic: {}. Response Status: {}",
- publishMessageRequest.getTopic(), response.getStatusCode());
- throw new BaseException("Failed to publish message with topic: " + publishMessageRequest.getTopic());
+ publishMessageRequestVO.getTopic(), response.getStatusCode());
+ throw new BaseException("Failed to publish message with topic: " + publishMessageRequestVO.getTopic());
}
} catch (HttpClientErrorException e) {
log.error("HTTP error occurred while publishing message: {}", e.getMessage());
@@ -70,19 +70,19 @@ public String publishMessage(PublishMessageRequest publishMessageRequest) throws
/**
* Makes the actual API call to publish a message.
*
- * @param publishMessageRequest Object containing the required parameters for publishing.
+ * @param publishMessageRequestVO Object containing the required parameters for publishing.
* @return R Response indicating success or failure from the BifroMQApi.
*/
- private ResponseEntity callPublishApi(PublishMessageRequest publishMessageRequest) {
+ private ResponseEntity callPublishApi(PublishMessageRequestVO publishMessageRequestVO) {
return bifroMQApi.publishMessage(
- publishMessageRequest.getReqId(),
- publishMessageRequest.getTenantId(),
- publishMessageRequest.getTopic(),
- publishMessageRequest.getClientType(),
- publishMessageRequest.getPubQos(),
- publishMessageRequest.getRetain(),
- publishMessageRequest.getClientMeta(),
- publishMessageRequest.getPayload()
+ publishMessageRequestVO.getReqId(),
+ publishMessageRequestVO.getTenantId(),
+ publishMessageRequestVO.getTopic(),
+ publishMessageRequestVO.getClientType(),
+ publishMessageRequestVO.getPubQos(),
+ publishMessageRequestVO.getRetain(),
+ publishMessageRequestVO.getClientMeta(),
+ publishMessageRequestVO.getPayload()
);
}
}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/resources/bootstrap.yml b/thinglinks-modules/thinglinks-modules-broker/src/main/resources/bootstrap.yml
index 1c22968f..52a6e1d4 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/resources/bootstrap.yml
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/resources/bootstrap.yml
@@ -33,5 +33,7 @@ spring:
refresh: false
- dataId: database.yml
refresh: true
+ - dataId: kafka.yml
+ refresh: false
username: @nacos.username@
password: @nacos.password@
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-link/pom.xml b/thinglinks-modules/thinglinks-modules-link/pom.xml
index 71f7f6bd..ade47d50 100644
--- a/thinglinks-modules/thinglinks-modules-link/pom.xml
+++ b/thinglinks-modules/thinglinks-modules-link/pom.xml
@@ -73,13 +73,6 @@
${thinglinks.version}
-
-
- com.mqttsnet
- thinglinks-common-rocketmq
- ${thinglinks.version}
-
-
com.mqttsnet
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/asyncthread/LinkAsyncConfig.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/asyncthread/LinkAsyncConfig.java
index b35d2638..1594caa1 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/asyncthread/LinkAsyncConfig.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/asyncthread/LinkAsyncConfig.java
@@ -52,7 +52,7 @@ public class LinkAsyncConfig {
* link服务全局共享异步线程池
*/
@Bean("linkAsync")
- public Executor tdengineAsync() {
+ public Executor linkAsync() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);//核心线程数
executor.setMaxPoolSize(maxPoolSize);//最大线程数 cpu核数/(1-0.8)//cup核数*2//cup核数+1
@@ -73,7 +73,7 @@ public Executor tdengineAsync() {
* MQTT设备消息消费异步线程池配置
*/
@Bean("linkAsync-mqttMsg")
- public Executor linkAsync() {
+ public Executor linkAsyncMqttMsg() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);//核心线程数
executor.setMaxPoolSize(maxPoolSize);//最大线程数 cpu核数/(1-0.8)//cup核数*2//cup核数+1
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/CacheSuperAbstract.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/CacheSuperAbstract.java
new file mode 100644
index 00000000..4c37a80c
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/CacheSuperAbstract.java
@@ -0,0 +1,11 @@
+package com.mqttsnet.thinglinks.link.common.cache;
+
+/**
+ * 缓存抽象类,提供共用方法
+ */
+public abstract class CacheSuperAbstract {
+
+ public static int PAGE_SIZE = 5000;
+
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/helper/CacheDataHelper.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/helper/CacheDataHelper.java
new file mode 100644
index 00000000..1cafe62f
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/helper/CacheDataHelper.java
@@ -0,0 +1,112 @@
+package com.mqttsnet.thinglinks.link.common.cache.helper;
+
+import com.mqttsnet.thinglinks.common.core.constant.CacheConstants;
+import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
+import com.mqttsnet.thinglinks.common.redis.service.RedisService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductModelCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDescribeVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * -----------------------------------------------------------------------------
+ * 文件名称: CacheDataHelper.java
+ * -----------------------------------------------------------------------------
+ * 描述:
+ * CacheDataHelper
+ * -----------------------------------------------------------------------------
+ *
+ * @author ShiHuan Sun
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * 修改历史:
+ * 日期 作者 版本 描述
+ * -------- -------- ------- --------------------
+ *
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023-10-12 22:26
+ */
+@Component
+@Slf4j
+public class CacheDataHelper {
+
+ private final RedisService redisService;
+
+ public CacheDataHelper(RedisService redisService) {
+ this.redisService = redisService;
+ }
+
+ public DeviceCacheVO getDeviceCacheVO(String deviceIdentification) {
+ if (deviceIdentification == null) {
+ log.warn("Device identification is null");
+ return null;
+ }
+ Device deviceCacheObject = redisService.getCacheObject(CacheConstants.DEVICE_RECORD_KEY + deviceIdentification);
+ return BeanPlusUtil.toBeanIgnoreError(deviceCacheObject, DeviceCacheVO.class);
+ }
+
+ public ProductModelCacheVO getProductModelCacheVO(String productIdentification) {
+ if (productIdentification == null) {
+ log.warn("Product identification is null");
+ return null;
+ }
+
+ ProductModelCacheVO objectCacheResult = redisService.getCacheObject(CacheConstants.DEVICE_RECORD_KEY + productIdentification);
+ return BeanPlusUtil.toBeanIgnoreError(objectCacheResult, ProductModelCacheVO.class);
+ }
+
+ public List getProductModelSuperTableCacheVO(String productIdentification, String serviceCode, String deviceIdentification) {
+ // 构造缓存键
+ String cacheKey = CacheConstants.PRODUCT_MODEL_SUPER_TABLE + productIdentification + ":" + serviceCode + ":" + deviceIdentification;
+
+ // 尝试从缓存获取数据
+ List cacheList;
+ try {
+ cacheList = redisService.getCacheList(cacheKey);
+ } catch (Exception e) {
+ log.error("Error fetching from cache for key: {}", cacheKey, e);
+ return Collections.emptyList();
+ }
+
+ // 检查缓存结果是否为空
+ if (cacheList == null || cacheList.isEmpty()) {
+ log.warn("The product model super table is not in the cache for key: {}", cacheKey);
+ return Collections.emptyList();
+ }
+
+ // 尝试将缓存结果转换为预期类型的列表
+ try {
+ // 这里假设所有缓存的对象都已经是SuperTableDescribeVO类型的实例
+ // 为了安全起见,我们进行一次类型检查
+ @SuppressWarnings("unchecked")
+ List result = (List) cacheList.stream()
+ .filter(SuperTableDescribeVO.class::isInstance)
+ .map(SuperTableDescribeVO.class::cast)
+ .collect(Collectors.toList());
+
+ if (result.isEmpty()) {
+ log.warn("The product model super table cache list is empty for key: {}", cacheKey);
+ }
+ return result;
+ } catch (ClassCastException e) {
+ log.error("Unexpected type in cached list for key: {}", cacheKey, e);
+ return Collections.emptyList();
+ }
+ }
+
+
+ public void setProductModelSuperTableCacheVO(String productIdentification, String serviceCode, String deviceIdentification,
+ List superTableDescribeOpt) {
+ String cacheKey = CacheConstants.PRODUCT_MODEL_SUPER_TABLE + productIdentification + ":" + serviceCode + ":" + deviceIdentification;
+ redisService.delete(cacheKey);
+ redisService.setCacheObject(cacheKey, superTableDescribeOpt);
+ }
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
new file mode 100644
index 00000000..1571484e
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
@@ -0,0 +1,133 @@
+package com.mqttsnet.thinglinks.link.common.cache.service;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
+import com.mqttsnet.thinglinks.common.redis.service.RedisService;
+import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import com.mqttsnet.thinglinks.link.common.cache.CacheSuperAbstract;
+import com.mqttsnet.thinglinks.link.service.device.DeviceService;
+import com.mqttsnet.thinglinks.link.service.product.ProductService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+/**
+ * -----------------------------------------------------------------------------
+ * File Name: DeviceCacheService.java
+ * -----------------------------------------------------------------------------
+ * Description:
+ * Service layer for Device cache management.
+ * -----------------------------------------------------------------------------
+ *
+ * @author ShiHuan Sun
+ * @version 1.0
+ * -----------------------------------------------------------------------------
+ * Revision History:
+ * Date Author Version Description
+ * -------- -------- ------- --------------------
+ *
+ * -----------------------------------------------------------------------------
+ * @email 13733918655@163.com
+ * @date 2023-10-21 22:42
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class DeviceCacheService extends CacheSuperAbstract {
+ private final RedisService redisService;
+ private final DeviceService deviceService;
+ private final ProductService productService;
+
+ /**
+ * Refresh the cache with device data for a specific tenant.
+ *
+ * @param tenantId Identifier of the tenant whose device cache needs to be refreshed.
+ */
+ public void refreshDeviceCacheForTenant(Long tenantId) {
+ int totalDataCount = deviceService.findDeviceTotal().intValue();
+ int totalPages = (int) Math.ceil((double) totalDataCount / PAGE_SIZE);
+
+ List deviceList = IntStream.range(0, totalPages)
+ .mapToObj(currentPage -> {
+ Page page = new Page<>(currentPage, PAGE_SIZE);
+ Page content = deviceService.page(page, null);
+ return Optional.ofNullable(content)
+ .map(Page::getRecords)
+ .orElse(Collections.emptyList());
+ })
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+
+ cacheDevicesForTenant(tenantId, deviceList);
+ }
+
+ /**
+ * Cache a list of devices for a specific tenant.
+ *
+ * @param tenantId Identifier of the tenant.
+ * @param deviceList List of devices to be cached.
+ */
+ public void cacheDevicesForTenant(Long tenantId, List deviceList) {
+ Optional.ofNullable(deviceList)
+ .orElse(Collections.emptyList())
+ .stream()
+ .filter(Objects::nonNull)
+ .map(device -> transformToDeviceCacheVO(tenantId, device))
+ .filter(Objects::nonNull)
+ .forEach(deviceCacheVO -> {
+ cacheDeviceBasedOnIdentification(deviceCacheVO);
+ cacheDeviceBasedOnClientId(deviceCacheVO);
+ });
+ }
+
+ /**
+ * Transforms a device object into a DeviceCacheVO object with associated product data.
+ *
+ * @param tenantId Identifier of the tenant.
+ * @param device Device object to be transformed.
+ * @return Transformed DeviceCacheVO object.
+ */
+ private DeviceCacheVO transformToDeviceCacheVO(Long tenantId, Device device) {
+ DeviceCacheVO deviceCacheVO = BeanUtil.toBeanIgnoreError(device, DeviceCacheVO.class);
+ deviceCacheVO.setTenantId(tenantId);
+
+ Optional.ofNullable(deviceCacheVO.getProductIdentification())
+ .map(productService::selectProductByProductIdentificationList)
+ .ifPresent(product -> {
+ ProductCacheVO productCacheVO = BeanPlusUtil.toBeanIgnoreError(product, ProductCacheVO.class);
+ productCacheVO.setTenantId(tenantId);
+ deviceCacheVO.setProductCacheVO(productCacheVO);
+ });
+
+ return deviceCacheVO;
+ }
+
+ /**
+ * Cache the DeviceCacheVO object based on its identification.
+ *
+ * @param deviceCacheVO DeviceCacheVO object to be cached.
+ */
+ private void cacheDeviceBasedOnIdentification(DeviceCacheVO deviceCacheVO) {
+ CacheKey deviceIdentKey = DeviceCacheKeyBuilder.build(deviceCacheVO.getDeviceIdentification());
+ cachePlusOps.del(deviceIdentKey);
+ cachePlusOps.set(deviceIdentKey, deviceCacheVO);
+ }
+
+ /**
+ * Cache the DeviceCacheVO object based on its client ID.
+ *
+ * @param deviceCacheVO DeviceCacheVO object to be cached.
+ */
+ private void cacheDeviceBasedOnClientId(DeviceCacheVO deviceCacheVO) {
+ CacheKey clientIdKey = DeviceCacheKeyBuilder.build(deviceCacheVO.getClientId());
+ cachePlusOps.del(clientIdKey);
+ cachePlusOps.set(clientIdKey, deviceCacheVO);
+ }
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
index 6e573661..5b09dc6e 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
@@ -3,7 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mqttsnet.thinglinks.common.core.enums.MqttEvent;
-import com.mqttsnet.thinglinks.common.kafka.constant.ConsumerTopicConstant;
+import com.mqttsnet.thinglinks.common.kafka.constant.ConsumerKafkaTopicConstant;
import com.mqttsnet.thinglinks.link.service.device.DeviceActionService;
import com.mqttsnet.thinglinks.link.service.device.DeviceDatasService;
import lombok.extern.slf4j.Slf4j;
@@ -27,6 +27,7 @@
*/
@Slf4j
//@Component
+@Deprecated
public class DeviceActionMessageKafkaConsumer {
@Autowired
private DeviceActionService deviceActionService;
@@ -35,15 +36,15 @@ public class DeviceActionMessageKafkaConsumer {
@Async("linkAsync")
@KafkaListener(topics = {
- ConsumerTopicConstant.THINGLINKS_LINK_MQTT_MSG,
- ConsumerTopicConstant.THINGLINKS_CLIENT_CONNECTED_TOPIC,
- ConsumerTopicConstant.THINGLINKS_CLIENT_DISCONNECTED_TOPIC,
- ConsumerTopicConstant.THINGLINKS_SERVER_CONNECTED_TOPIC,
- ConsumerTopicConstant.THINGLINKS_DEVICE_KICKED_TOPIC,
- ConsumerTopicConstant.THINGLINKS_SUBSCRIPTION_ACKED_TOPIC,
- ConsumerTopicConstant.THINGLINKS_UNSUBSCRIPTION_ACKED_TOPIC,
- ConsumerTopicConstant.THINGLINKS_DISTRIBUTION_ERROR_TOPIC,
- ConsumerTopicConstant.THINGLINKS_DISTRIBUTION_COMPLETED_TOPIC})
+ ConsumerKafkaTopicConstant.THINGLINKS_LINK_MQTT_MSG,
+ ConsumerKafkaTopicConstant.THINGLINKS_CLIENT_CONNECTED_TOPIC,
+ ConsumerKafkaTopicConstant.THINGLINKS_CLIENT_DISCONNECTED_TOPIC,
+ ConsumerKafkaTopicConstant.THINGLINKS_SERVER_CONNECTED_TOPIC,
+ ConsumerKafkaTopicConstant.THINGLINKS_DEVICE_KICKED_TOPIC,
+ ConsumerKafkaTopicConstant.THINGLINKS_SUBSCRIPTION_ACKED_TOPIC,
+ ConsumerKafkaTopicConstant.THINGLINKS_UNSUBSCRIPTION_ACKED_TOPIC,
+ ConsumerKafkaTopicConstant.THINGLINKS_DISTRIBUTION_ERROR_TOPIC,
+ ConsumerKafkaTopicConstant.THINGLINKS_DISTRIBUTION_COMPLETED_TOPIC})
public void onMessage(ConsumerRecord, ?> record) {
if (null == record) {
log.warn("message cannot be empty {}", record);
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
index 7c2afd17..0f0bfbb5 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
@@ -29,6 +29,7 @@
*/
@Slf4j
//@Component
+@Deprecated
@RocketMQMessageListener(consumerGroup = ConsumerGroupConstant.THINGLINKS_BROKER_GROUP, topic = ConsumerTopicConstant.THINGLINKS_LINK_MQTT_MSG, messageModel = MessageModel.CLUSTERING)
public class DeviceActionMessageRocketmqConsumer implements RocketMQListener {
@Autowired
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/listener/RedisKeyExpirationListener.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/listener/RedisKeyExpirationListener.java
index d6083f70..0653d283 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/listener/RedisKeyExpirationListener.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/listener/RedisKeyExpirationListener.java
@@ -1,5 +1,6 @@
package com.mqttsnet.thinglinks.link.common.listener;
+import com.mqttsnet.thinglinks.common.core.constant.CacheConstants;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.text.UUID;
import com.mqttsnet.thinglinks.common.redis.service.RedisService;
@@ -50,9 +51,9 @@ public void onMessage(Message message, byte[] pattern) {
resultLock = redisService.checkLock(expiredKey, uuid, 1000L);
if (resultLock) {
log.info("获取分布式锁成功-key:{},value:{}", expiredKey, uuid);
- if (expiredKey.contains(Constants.DEVICE_RECORD_KEY)){
+ if (expiredKey.contains(CacheConstants.DEVICE_RECORD_KEY)){
log.info("设备信息缓存失效{}",expiredKey);
- deviceService.cacheInvalidation(expiredKey.replace(Constants.DEVICE_RECORD_KEY, ""));
+ deviceService.cacheInvalidation(expiredKey.replace(CacheConstants.DEVICE_RECORD_KEY, ""));
}
}else {
log.info("获取分布式锁失败-key:{},value:{}", expiredKey, uuid);
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
index 230f9b38..b6e0436d 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
@@ -1,10 +1,8 @@
package com.mqttsnet.thinglinks.link.controller.device;
-import cn.hutool.json.JSONConverter;
-import com.alibaba.fastjson.JSON;
import com.mqttsnet.thinglinks.common.core.annotation.NoRepeatSubmit;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatus;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
import com.mqttsnet.thinglinks.common.core.utils.StringUtils;
import com.mqttsnet.thinglinks.common.core.utils.poi.ExcelUtil;
import com.mqttsnet.thinglinks.common.core.web.controller.BaseController;
@@ -16,17 +14,26 @@
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
import com.mqttsnet.thinglinks.link.api.domain.device.model.DeviceParams;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.OtaCommandResponseParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoAddSubDeviceParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoQueryDeviceParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoUpdateSubDeviceStatusParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
import com.mqttsnet.thinglinks.link.service.device.DeviceService;
import com.mqttsnet.thinglinks.link.service.product.ProductService;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -96,11 +103,11 @@ public AjaxResult listStatusCount(Device device) {
Map countMap = new HashMap<>();
//统计设备在线数量
- countMap.put("onlineCount", !connectStatusCollect.isEmpty() && !CollectionUtils.isEmpty(connectStatusCollect.get(DeviceConnectStatus.ONLINE.getValue())) ? connectStatusCollect.get(DeviceConnectStatus.ONLINE.getValue()).size() : 0);
+ countMap.put("onlineCount", !connectStatusCollect.isEmpty() && !CollectionUtils.isEmpty(connectStatusCollect.get(DeviceConnectStatusEnum.ONLINE.getValue())) ? connectStatusCollect.get(DeviceConnectStatusEnum.ONLINE.getValue()).size() : 0);
//统计设备离线数量
- countMap.put("offlineCount", !connectStatusCollect.isEmpty() && !CollectionUtils.isEmpty(connectStatusCollect.get(DeviceConnectStatus.OFFLINE.getValue())) ? connectStatusCollect.get(DeviceConnectStatus.OFFLINE.getValue()).size() : 0);
+ countMap.put("offlineCount", !connectStatusCollect.isEmpty() && !CollectionUtils.isEmpty(connectStatusCollect.get(DeviceConnectStatusEnum.OFFLINE.getValue())) ? connectStatusCollect.get(DeviceConnectStatusEnum.OFFLINE.getValue()).size() : 0);
//统计设备初始化数量
- countMap.put("initCount", !connectStatusCollect.isEmpty() && !CollectionUtils.isEmpty(connectStatusCollect.get(DeviceConnectStatus.INIT.getValue())) ? connectStatusCollect.get(DeviceConnectStatus.INIT.getValue()).size() : 0);
+ countMap.put("initCount", !connectStatusCollect.isEmpty() && !CollectionUtils.isEmpty(connectStatusCollect.get(DeviceConnectStatusEnum.INIT.getValue())) ? connectStatusCollect.get(DeviceConnectStatusEnum.INIT.getValue()).size() : 0);
return AjaxResult.success(countMap);
}
@@ -237,6 +244,7 @@ public AjaxResult disconnect(@PathVariable Long[] ids) {
* @param params
* @return
*/
+ @Deprecated
@PostMapping("/clientAuthentication")
public ResponseEntity clientAuthentication(@RequestBody Map params) {
final Object clientIdentifier = params.get("clientIdentifier");
@@ -307,4 +315,168 @@ public R> selectAllByProductIdentification(@PathVariable(value = "p
public R> selectDeviceByDeviceIdentificationList(@RequestBody List deviceIdentificationList) {
return R.ok(deviceService.selectDeviceByDeviceIdentificationList(deviceIdentificationList));
}
+
+
+ /**
+ * (MQTT)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @ApiOperation(value = "(MQTT)协议新增子设备档案", httpMethod = "POST", notes = "(MQTT)协议新增子设备档案")
+ @PostMapping("/saveSubDeviceByMqtt")
+ public R saveSubDeviceByMqtt(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return R.ok(deviceService.saveSubDeviceByMqtt(topoAddSubDeviceParam));
+ }
+
+ /**
+ * (HTTP)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @ApiOperation(value = "(HTTP)协议新增子设备档案", httpMethod = "POST", notes = "(HTTP)协议新增子设备档案")
+ @PostMapping("/saveSubDeviceByHttp")
+ public R saveSubDeviceByHttp(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return R.ok(deviceService.saveSubDeviceByHttp(topoAddSubDeviceParam));
+ }
+
+ /**
+ * MQTT协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(MQTT)协议修改子设备连接状态", httpMethod = "PUT", notes = "(MQTT)协议修改子设备连接状态")
+ @PutMapping("/updateSubDeviceConnectStatusByMqtt")
+ public R updateSubDeviceConnectStatusByMqtt(
+ @RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.updateSubDeviceConnectStatusByMqtt(topoUpdateSubDeviceStatusParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * HTTP协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(HTTP)协议修改子设备连接状态", httpMethod = "PUT", notes = "(HTTP)协议修改子设备连接状态")
+ @PutMapping("/updateSubDeviceConnectStatusByHttp")
+ public R updateSubDeviceConnectStatusByHttp(
+ @RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.updateSubDeviceConnectStatusByHttp(topoUpdateSubDeviceStatusParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * MQTT协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(MQTT)协议删除子设备", httpMethod = "PUT", notes = "(MQTT)协议删除子设备")
+ @PutMapping("/deleteSubDeviceByMqtt")
+ public R deleteSubDeviceByMqtt(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deleteSubDeviceByMqtt(topoDeleteSubDeviceParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * HTTP协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(HTTP)协议删除子设备", httpMethod = "PUT", notes = "(HTTP)协议删除子设备")
+ @PutMapping("/deleteSubDeviceByHttp")
+ public R deleteSubDeviceByHttp(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deleteSubDeviceByHttp(topoDeleteSubDeviceParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+
+ /**
+ * MQTT协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @ApiOperation(value = "(MQTT)协议数据上报", httpMethod = "POST", notes = "(MQTT)协议数据上报")
+ @PostMapping("/deviceDataReportByMqtt")
+ public R deviceDataReportByMqtt(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deviceDataReportByMqtt(topoDeviceDataReportParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * HTTP协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @ApiOperation(value = "(HTTP)协议数据上报", httpMethod = "POST", notes = "(HTTP)协议数据上报")
+ @PostMapping("/deviceDataReportByHttp")
+ public R deviceDataReportByHttp(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deviceDataReportByHttp(topoDeviceDataReportParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * Queries device information using the HTTP protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @ApiOperation(value = "Query Device Information via HTTP Protocol", httpMethod = "POST", notes = "Queries device information using the HTTP protocol")
+ @PostMapping("/queryDeviceByHttp")
+ public R queryDeviceByHttp(@RequestBody TopoQueryDeviceParam topoQueryDeviceParam) {
+ return R.ok(deviceService.queryDeviceByHttp(topoQueryDeviceParam));
+ }
+
+ /**
+ * Receives and saves a new OTA upgrade record from an MQTT message. This endpoint
+ * captures the command response parameters from the MQTT message body and persists them.
+ *
+ * @param otaCommandResponseParam The response parameters from an OTA command sent via MQTT.
+ * @return {@link R} A response entity containing the saved OTA upgrade record.
+ */
+ @ApiOperation(value = "Save OTA Upgrade Record", httpMethod = "POST", notes = "Saves a new OTA upgrade record from MQTT message data.")
+ @PostMapping("/saveOtaUpgradeRecordByMqtt")
+ public R saveOtaUpgradeRecordByMqtt(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam) {
+ try {
+ // Call the service method to save the record
+ OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveOtaUpgradeRecordByMqtt(otaCommandResponseParam);
+
+ // Return a successful response entity with the saved record
+ return R.ok(savedRecord);
+ } catch (Exception e) {
+ // Log the exception and return an error response entity
+ // Assuming R.fail() is a method to create a failure response
+ return R.fail("Error saving OTA upgrade record: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Receives and saves a new OTA upgrade record from an HTTP request. This endpoint
+ * captures the command response parameters from the request body and persists them.
+ *
+ * @param otaCommandResponseParam The response parameters from an OTA command sent via HTTP.
+ * @return {@link R} A response wrapper containing the saved OTA upgrade record.
+ */
+ @ApiOperation(value = "Save OTA Upgrade Record via HTTP", httpMethod = "POST", notes = "Saves a new OTA upgrade record from HTTP request data.")
+ @PostMapping("/saveUpgradeRecordByHttp")
+ public R saveUpgradeRecordByHttp(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam) {
+ try {
+ // Call the service method to save the record
+ OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveUpgradeRecordByHttp(otaCommandResponseParam);
+
+ // Return a successful response wrapper with the saved record
+ return R.ok(savedRecord);
+ } catch (Exception e) {
+ // Log the exception and return a failure response wrapper
+ // Assuming R.fail() is a method to create a failure response
+ return R.fail("Error saving OTA upgrade record via HTTP: " + e.getMessage());
+ }
+ }
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceActionServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceActionServiceImpl.java
index 79970a7b..294b09de 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceActionServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceActionServiceImpl.java
@@ -3,7 +3,7 @@
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
-import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatus;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
import com.mqttsnet.thinglinks.common.core.utils.DateUtils;
import com.mqttsnet.thinglinks.common.redis.service.RedisService;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
@@ -116,7 +116,7 @@ public void connectEvent(JSONObject thinglinksMessage) {
Gson gson = new Gson();
Map map = new HashMap<>();
map = gson.fromJson(thinglinksMessage.toJSONString(), map.getClass());
- deviceService.updateConnectStatusByClientId(DeviceConnectStatus.ONLINE.getValue(), String.valueOf(map.get("clientId")));
+ deviceService.updateConnectStatusByClientId(DeviceConnectStatusEnum.ONLINE.getValue(), String.valueOf(map.get("clientId")));
}
/**
@@ -129,7 +129,7 @@ public void closeEvent(JSONObject thinglinksMessage) {
Gson gson = new Gson();
Map map = new HashMap<>();
map = gson.fromJson(thinglinksMessage.toJSONString(), map.getClass());
- deviceService.updateConnectStatusByClientId(DeviceConnectStatus.OFFLINE.getValue(), String.valueOf(map.get("clientId")));
+ deviceService.updateConnectStatusByClientId(DeviceConnectStatusEnum.OFFLINE.getValue(), String.valueOf(map.get("clientId")));
}
@@ -230,7 +230,7 @@ public void refreshDeviceCache(JSONObject thinglinksMessage) {
Device device = deviceService.findOneByClientId(String.valueOf(map.get("clientId")));
if (null != device){
//缓存设备信息
- redisService.setCacheObject(Constants.DEVICE_RECORD_KEY+device.getClientId(),device,60L+ Long.parseLong(DateUtils.getRandom(1)), TimeUnit.SECONDS);
+ redisService.setCacheObject(CacheConstants.DEVICE_RECORD_KEY+device.getClientId(),device,60L+ Long.parseLong(DateUtils.getRandom(1)), TimeUnit.SECONDS);
}
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceDatasServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceDatasServiceImpl.java
index 24ef248a..235268fe 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceDatasServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceDatasServiceImpl.java
@@ -7,13 +7,14 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.JsonPath;
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.common.core.constant.CacheConstants;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.dynamicCompilation.ClassInjector;
import com.mqttsnet.thinglinks.common.core.dynamicCompilation.DynamicClassLoader;
import com.mqttsnet.thinglinks.common.core.dynamicCompilation.DynamicLoaderEngine;
import com.mqttsnet.thinglinks.common.core.dynamicCompilation.bytecode.InjectionSystem;
-import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatus;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
import com.mqttsnet.thinglinks.common.core.enums.DeviceType;
import com.mqttsnet.thinglinks.common.core.enums.ProtocolType;
import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
@@ -225,7 +226,7 @@ public void insertBaseDatas(JSONObject thinglinksMessage) throws Exception {
* 处理/topo/add Topic边设备添加子设备
*
* @param deviceIdentification 设备标识
- * @param body 数据
+ * @param body 数据
*/
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@@ -261,7 +262,7 @@ public String processingTopoAddTopic(String deviceIdentification, String body) t
deviceInfo.setDescription(deviceInfos.getDescription());
deviceInfo.setManufacturerId(deviceInfos.getManufacturerId());
deviceInfo.setModel(deviceInfos.getModel());
- deviceInfo.setConnectStatus(DeviceConnectStatus.INIT.getValue());
+ deviceInfo.setConnectStatus(DeviceConnectStatusEnum.INIT.getValue());
deviceInfo.setShadowEnable(true);
StringBuilder shadowTableNameBuilder = new StringBuilder();
// 新增设备管理成功后,创建TD普通表
@@ -321,7 +322,7 @@ public String processingTopoAddTopic(String deviceIdentification, String body) t
* 处理/topo/delete Topic边设备删除子设备
*
* @param deviceIdentification 设备标识
- * @param body 数据
+ * @param body 数据
*/
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@@ -360,7 +361,7 @@ public String processingTopoDeleteTopic(String deviceIdentification, String body
* 处理/topo/update Topic边设备更新子设备状态
*
* @param deviceIdentification 设备标识
- * @param body 数据
+ * @param body 数据
*/
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@@ -389,9 +390,9 @@ public String processingTopoUpdateTopic(String deviceIdentification, String body
log.error("The side device reports data processing, but the device does not exist,DeviceIdentification:{},Body:{}", deviceIdentification, body);
}
if ("ONLINE".equals(status)) {
- deviceInfo.setConnectStatus(DeviceConnectStatus.ONLINE.getValue());
+ deviceInfo.setConnectStatus(DeviceConnectStatusEnum.ONLINE.getValue());
} else if ("OFFLINE".equals(status)) {
- deviceInfo.setConnectStatus(DeviceConnectStatus.OFFLINE.getValue());
+ deviceInfo.setConnectStatus(DeviceConnectStatusEnum.OFFLINE.getValue());
}
final int updateByPrimaryKeySelectiveCount = deviceInfoService.updateByPrimaryKeySelective(deviceInfo);
if (updateByPrimaryKeySelectiveCount > 0) {
@@ -413,7 +414,7 @@ public String processingTopoUpdateTopic(String deviceIdentification, String body
* 处理datas Topic数据上报
*
* @param deviceIdentification 设备标识
- * @param body 数据
+ * @param body 数据
*/
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@@ -426,12 +427,12 @@ public void processingDatasTopic(String deviceIdentification, String body) throw
for (Map item : items) {
final Object deviceId = item.get("deviceId");
Device device = null;
- if (Boolean.TRUE.equals(redisService.hasKey(Constants.DEVICE_RECORD_KEY + deviceIdentification))) {
- device = redisService.getCacheObject(Constants.DEVICE_RECORD_KEY + deviceIdentification);
+ if (Boolean.TRUE.equals(redisService.hasKey(CacheConstants.DEVICE_RECORD_KEY + deviceIdentification))) {
+ device = redisService.getCacheObject(CacheConstants.DEVICE_RECORD_KEY + deviceIdentification);
} else {
device = deviceService.findOneByDeviceIdentification(deviceIdentification);
if (StringUtils.isNotNull(device)) {
- redisService.setCacheObject(Constants.DEVICE_RECORD_KEY + deviceIdentification, device);
+ redisService.setCacheObject(CacheConstants.DEVICE_RECORD_KEY + deviceIdentification, device);
} else {
log.error("The side device reports data processing, but the device does not exist,DeviceIdentification:{},Body:{}", deviceIdentification, body);
continue;
@@ -471,7 +472,7 @@ public void processingDatasTopic(String deviceIdentification, String body) throw
//子表命名规则 : 产品类型_产品标识_服务名称_设备标识(设备唯一标识)
String tableName = superTableName + "_" + deviceId.toString();
//从redis根据超级表名称取出超级表表结构信息
- final Object cacheObject = redisService.getCacheObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName);
+ final Object cacheObject = redisService.getCacheObject(CacheConstants.TDENGINE_SUPERTABLEFILELDS + superTableName);
ObjectMapper objectMapper = new ObjectMapper();
SuperTableDto superTableDto = objectMapper.convertValue(cacheObject, SuperTableDto.class);
//获取超级表的表结构信息
@@ -554,7 +555,7 @@ public void processingDatasTopic(String deviceIdentification, String body) throw
* 处理/commandResponse Topic边设备返回给物联网平台的命令响应
*
* @param deviceIdentification 设备标识
- * @param body 数据
+ * @param body 数据
*/
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@@ -567,8 +568,8 @@ public void processingTopoCommandResponseTopic(String deviceIdentification, Stri
* 根据设备找到所属产品 产品的服务及属性 转换出系统能识别的json 找到这个产品的协议内容即Java代码
*/
public String convertToBody(String deviceIdentification, String body) {
- if (Boolean.TRUE.equals(redisService.hasKey(Constants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + ProtocolType.MQTT.getValue() + deviceIdentification))) {
- String protocolContent = redisService.get(Constants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + ProtocolType.MQTT.getValue() + deviceIdentification);
+ if (Boolean.TRUE.equals(redisService.hasKey(CacheConstants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + ProtocolType.MQTT.getValue() + deviceIdentification))) {
+ String protocolContent = redisService.get(CacheConstants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + ProtocolType.MQTT.getValue() + deviceIdentification);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
PrintWriter out = new PrintWriter(buffer, true);
byte[] classBytes = DynamicLoaderEngine.compile(protocolContent, out, null);//传入要执行的代码
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceInfoServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceInfoServiceImpl.java
index 8e55a4a5..fbf65740 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceInfoServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceInfoServiceImpl.java
@@ -4,7 +4,7 @@
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatus;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
import com.mqttsnet.thinglinks.common.core.text.UUID;
import com.mqttsnet.thinglinks.common.core.utils.DateUtils;
@@ -181,7 +181,7 @@ public int insertDeviceInfo(DeviceInfoParams deviceInfoParams)
SysUser sysUser = loginUser.getSysUser();
deviceInfo.setCreateBy(sysUser.getUserName());
deviceInfo.setDeviceId(UUID.getUUID());
- deviceInfo.setConnectStatus(DeviceConnectStatus.INIT.getValue());
+ deviceInfo.setConnectStatus(DeviceConnectStatusEnum.INIT.getValue());
deviceInfo.setShadowEnable(true);
return deviceInfoMapper.insertDeviceInfo(deviceInfo);
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceServiceImpl.java
index d86eb92a..8e0ce933 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceServiceImpl.java
@@ -1,9 +1,10 @@
package com.mqttsnet.thinglinks.link.service.device.impl;
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
+import com.mqttsnet.thinglinks.common.core.constant.CacheConstants;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatus;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
import com.mqttsnet.thinglinks.common.core.enums.DeviceTopicEnum;
import com.mqttsnet.thinglinks.common.core.enums.DeviceType;
import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
@@ -224,7 +225,7 @@ public int insertDevice(DeviceParams deviceParams) throws Exception {
if (StringUtils.isNotNull(oneByClientIdAndDeviceIdentification)) {
throw new Exception("设备编号或者设备标识已存在");
}
- device.setConnectStatus(DeviceConnectStatus.INIT.getValue());
+ device.setConnectStatus(DeviceConnectStatusEnum.INIT.getValue());
device.setCreateBy(sysUser.getUserName());
final int insertDeviceCount = deviceMapper.insertOrUpdateSelective(device);
if (insertDeviceCount > 0) {
@@ -363,11 +364,11 @@ public Boolean cacheInvalidation(String clientId) {
//设备信息缓存失效 删除缓存 更新数据库设备状态
if (StringUtils.isNotNull(oneByClientId)) {
//删除缓存
- redisService.delete(Constants.DEVICE_RECORD_KEY + oneByClientId.getDeviceIdentification());
+ redisService.delete(CacheConstants.DEVICE_RECORD_KEY + oneByClientId.getDeviceIdentification());
//更新数据库设备状态
Device device = new Device();
device.setId(oneByClientId.getId());
- device.setConnectStatus(DeviceConnectStatus.OFFLINE.getValue());
+ device.setConnectStatus(DeviceConnectStatusEnum.OFFLINE.getValue());
deviceMapper.updateByPrimaryKeySelective(device);
}
return true;
@@ -416,9 +417,9 @@ public Device clientAuthentication(String clientIdentifier, String username, Str
final Device device = this.findOneByClientIdAndUserNameAndPasswordAndDeviceStatusAndProtocolType(clientIdentifier, username, password, deviceStatus, protocolType);
if (Optional.ofNullable(device).isPresent()) {
//缓存设备信息
- redisService.setCacheObject(Constants.DEVICE_RECORD_KEY + device.getDeviceIdentification(), device, 60L + Long.parseLong(DateUtils.getRandom(1)), TimeUnit.SECONDS);
+ redisService.setCacheObject(CacheConstants.DEVICE_RECORD_KEY + device.getDeviceIdentification(), device, 60L + Long.parseLong(DateUtils.getRandom(1)), TimeUnit.SECONDS);
//更改设备在线状态为在线
- this.updateConnectStatusByClientId(DeviceConnectStatus.ONLINE.getValue(), clientIdentifier);
+ this.updateConnectStatusByClientId(DeviceConnectStatusEnum.ONLINE.getValue(), clientIdentifier);
return device;
}
return null;
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
index a22b21fa..ba4f3e3c 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
@@ -5,6 +5,7 @@
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.jayway.jsonpath.JsonPath;
+import com.mqttsnet.thinglinks.common.core.constant.CacheConstants;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.enums.DataTypeEnum;
@@ -408,11 +409,11 @@ public AjaxResult createSuperTable(Product product, JSONArray services) throws E
}
log.info("Create SuperTable Result: {}", cstResult.getCode());
//将之前存在redis里的同样的名称的超级表的表结构信息删除
- if (redisService.hasKey(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName)) {
- redisService.deleteObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName);
+ if (redisService.hasKey(CacheConstants.TDENGINE_SUPERTABLEFILELDS + superTableName)) {
+ redisService.deleteObject(CacheConstants.TDENGINE_SUPERTABLEFILELDS + superTableName);
}
//在redis里存入新的超级表对的表结构信息
- redisService.setCacheObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName, superTableDto);
+ redisService.setCacheObject(CacheConstants.TDENGINE_SUPERTABLEFILELDS + superTableName, superTableDto);
log.info("缓存超级表数据模型:{}", JSON.toJSONString(superTableDto));
}
} catch (Exception e) {
@@ -649,11 +650,11 @@ public List createSuperTableDataModel(Long[] productIds, Boolean
//设置超级表标签字段列表
superTableDto.setTagsFields(tagsFields);
//将之前存在redis里的同样的名称的超级表的表结构信息删除
- if (redisService.hasKey(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName)) {
- redisService.deleteObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName);
+ if (redisService.hasKey(CacheConstants.TDENGINE_SUPERTABLEFILELDS + superTableName)) {
+ redisService.deleteObject(CacheConstants.TDENGINE_SUPERTABLEFILELDS + superTableName);
}
//在redis里存入新的超级表对的表结构信息
- redisService.setCacheObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName, superTableDto);
+ redisService.setCacheObject(CacheConstants.TDENGINE_SUPERTABLEFILELDS + superTableName, superTableDto);
log.info("缓存超级表数据模型:{}", JSON.toJSONString(superTableDto));
superTableDtoList.add(superTableDto);
if (Boolean.TRUE.equals(InitializeOrNot)) {
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/protocol/impl/ProtocolServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/protocol/impl/ProtocolServiceImpl.java
index d22d353b..ee3fd85a 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/protocol/impl/ProtocolServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/protocol/impl/ProtocolServiceImpl.java
@@ -1,5 +1,6 @@
package com.mqttsnet.thinglinks.link.service.protocol.impl;
+import com.mqttsnet.thinglinks.common.core.constant.CacheConstants;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.exception.ServiceException;
import com.mqttsnet.thinglinks.common.redis.service.RedisService;
@@ -170,7 +171,7 @@ public int enable(Long[] ids) {
List deviceList = deviceService.findAllByProductIdentification(protocol.getProductIdentification());
String content = StringEscapeUtils.unescapeHtml4(protocol.getContent());
for (Device device : deviceList) {
- redisService.set(Constants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + device.getProtocolType() + device.getDeviceIdentification(), content);
+ redisService.set(CacheConstants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + device.getProtocolType() + device.getDeviceIdentification(), content);
}
protocolMapper.updateStatusById(Constants.ENABLE, protocol.getId());
}
@@ -189,7 +190,7 @@ public int disable(Long[] ids) {
for (Protocol protocol : protocolList) {
List deviceList = deviceService.findAllByProductIdentification(protocol.getProductIdentification());
for (Device device : deviceList) {
- redisService.delete(Constants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + protocol.getProtocolType() + device.getDeviceIdentification());
+ redisService.delete(CacheConstants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + protocol.getProtocolType() + device.getDeviceIdentification());
}
protocolMapper.updateStatusById(Constants.DISABLE, protocol.getId());
}
@@ -217,7 +218,7 @@ public int protocolScriptCacheRefresh() {
for (Protocol protocol : protocolList) {
List deviceList = deviceService.findAllByProductIdentification(protocol.getProductIdentification());
for (Device device : deviceList) {
- redisService.delete(Constants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + protocol.getProtocolType() + device.getDeviceIdentification());
+ redisService.delete(CacheConstants.DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT + protocol.getProtocolType() + device.getDeviceIdentification());
}
protocolMapper.updateStatusById(Constants.DISABLE, protocol.getId());
}
diff --git a/thinglinks-modules/thinglinks-modules-rule/pom.xml b/thinglinks-modules/thinglinks-modules-rule/pom.xml
index 87083355..c5cab27d 100644
--- a/thinglinks-modules/thinglinks-modules-rule/pom.xml
+++ b/thinglinks-modules/thinglinks-modules-rule/pom.xml
@@ -45,6 +45,14 @@
mysql-connector-java
+
+
+ com.mqttsnet
+ thinglinks-common-core
+ ${thinglinks.version}
+
+
+
com.mqttsnet
diff --git a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/common/consumer/rocketmq/RuleTriggerMessageRocketmqConsumer.java b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/common/consumer/rocketmq/RuleTriggerMessageRocketmqConsumer.java
index 80aa4792..2be09743 100644
--- a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/common/consumer/rocketmq/RuleTriggerMessageRocketmqConsumer.java
+++ b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/common/consumer/rocketmq/RuleTriggerMessageRocketmqConsumer.java
@@ -1,8 +1,8 @@
package com.mqttsnet.thinglinks.rule.common.consumer.rocketmq;
import com.alibaba.fastjson.JSONObject;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerGroupConstant;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerTopicConstant;
+import com.mqttsnet.thinglinks.common.core.mqs.ConsumerGroupConstant;
+import com.mqttsnet.thinglinks.common.core.mqs.ConsumerTopicConstant;
import com.mqttsnet.thinglinks.rule.service.RuleDeviceLinkageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.MessageModel;
@@ -10,7 +10,6 @@
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Component;
/**
* @Description: 规则引擎-触发器规则消息消费(Rocketmq模式)
@@ -25,7 +24,7 @@
*/
@Slf4j
//@Component
-@RocketMQMessageListener(consumerGroup = ConsumerGroupConstant.THINGLINKS_RULE_GROUP, topic = ConsumerTopicConstant.THINGLINKS_RULE_TRIGGER, messageModel = MessageModel.CLUSTERING)
+@RocketMQMessageListener(consumerGroup = ConsumerGroupConstant.THINGLINKS_GROUP, topic = ConsumerTopicConstant.Rule.THINGLINKS_RULE_TRIGGER, messageModel = MessageModel.CLUSTERING)
public class RuleTriggerMessageRocketmqConsumer implements RocketMQListener {
@Autowired
diff --git a/thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/common/consumer/rocketmq/ProductCreateSuperTableMessageRocketmqConsumer.java b/thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/common/consumer/rocketmq/ProductCreateSuperTableMessageRocketmqConsumer.java
index 97593ef2..26306011 100644
--- a/thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/common/consumer/rocketmq/ProductCreateSuperTableMessageRocketmqConsumer.java
+++ b/thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/common/consumer/rocketmq/ProductCreateSuperTableMessageRocketmqConsumer.java
@@ -1,16 +1,15 @@
package com.mqttsnet.thinglinks.tdengine.common.consumer.rocketmq;
import com.alibaba.fastjson.JSONObject;
+import com.mqttsnet.thinglinks.common.core.mqs.ConsumerGroupConstant;
+import com.mqttsnet.thinglinks.common.core.mqs.ConsumerTopicConstant;
import com.mqttsnet.thinglinks.common.core.utils.StringUtils;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerGroupConstant;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerTopicConstant;
import com.mqttsnet.thinglinks.tdengine.service.ProductSuperTableCreateOrUpdateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
/**
* @Description: TDengine超级表创键修改动作监听(Rocketmq模式)
@@ -25,7 +24,7 @@
*/
@Slf4j
//@Component
-@RocketMQMessageListener(consumerGroup = ConsumerGroupConstant.THINGLINKS_LINK_GROUP, topic = ConsumerTopicConstant.PRODUCTSUPERTABLE_CREATEORUPDATE, messageModel = MessageModel.CLUSTERING)
+@RocketMQMessageListener(consumerGroup = ConsumerGroupConstant.THINGLINKS_GROUP, topic = ConsumerTopicConstant.Tdengine.PRODUCTSUPERTABLE_CREATEORUPDATE, messageModel = MessageModel.CLUSTERING)
public class ProductCreateSuperTableMessageRocketmqConsumer implements RocketMQListener {
@Autowired
@@ -33,6 +32,7 @@ public class ProductCreateSuperTableMessageRocketmqConsumer implements RocketMQL
/**
* 超级表创建及修改处理
+ *
* @param message
*/
@Override
@@ -42,14 +42,14 @@ public void onMessage(Object message) {
return;
}
JSONObject stableMessage = JSONObject.parseObject(String.valueOf(message));
- log.info("TDengine消费{}超级表消息:{}",stableMessage.get("type"),stableMessage.get("msg"));
- if("create".equals(stableMessage.get("type"))){
+ log.info("TDengine消费{}超级表消息:{}", stableMessage.get("type"), stableMessage.get("msg"));
+ if ("create".equals(stableMessage.get("type"))) {
try {
productSuperTableCreateOrUpdateService.createProductSuperTable(String.valueOf(stableMessage.get("msg")));
} catch (Exception e) {
log.error(e.getMessage());
}
- }else if("update".equals(stableMessage.get("type"))){
+ } else if ("update".equals(stableMessage.get("type"))) {
productSuperTableCreateOrUpdateService.updateProductSuperTable(String.valueOf(stableMessage.get("msg")));
}
From 58c002f1004a990f62fcc8528b1c37ef278911b9 Mon Sep 17 00:00:00 2001
From: xiaonan <13733918655@163.com>
Date: Tue, 5 Mar 2024 16:02:30 +0800
Subject: [PATCH 08/35] fix link error
---
.../DEFAULT_GROUP/thinglinks-modules-link.yml | 2 +-
.../DEFAULT_GROUP/thinglinks-modules-rule.yml | 2 +-
.../domain/cache/device/DeviceCacheVO.java | 1 -
.../domain/cache/product/ProductCacheVO.java | 1 -
.../cache/product/ProductModelCacheVO.java | 3 +-
.../param/TopoUpdateSubDeviceStatusParam.java | 2 +-
.../common/core/constant/CacheConstants.java | 7 +
.../core/mqs/ConsumerGroupConstant.java | 2 +-
.../thinglinks-modules-link/pom.xml | 7 -
.../cache/service/DeviceCacheService.java | 266 +++++++++---------
.../common/config/KafkaConsumerConfig.java | 109 -------
.../common/config/KafkaProviderConfig.java | 90 ------
.../DeviceActionMessageKafkaConsumer.java | 85 ------
.../DeviceActionMessageRocketmqConsumer.java | 79 ------
.../controller/device/DeviceController.java | 15 +-
.../controller/kafka/KafkaController.java | 38 ---
.../link/service/device/DeviceService.java | 96 ++++++-
.../device/impl/DeviceActionServiceImpl.java | 1 +
.../device/impl/DeviceServiceImpl.java | 114 ++++++++
.../product/impl/ProductServiceImpl.java | 11 +-
.../impl/RuleDeviceLinkageServiceImpl.java | 4 +-
.../src/main/resources/bootstrap.yml | 2 +-
22 files changed, 363 insertions(+), 574 deletions(-)
delete mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaConsumerConfig.java
delete mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaProviderConfig.java
delete mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
delete mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
delete mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/kafka/KafkaController.java
diff --git a/doc/nacos-config/DEFAULT_GROUP/thinglinks-modules-link.yml b/doc/nacos-config/DEFAULT_GROUP/thinglinks-modules-link.yml
index abccaa25..1995e460 100755
--- a/doc/nacos-config/DEFAULT_GROUP/thinglinks-modules-link.yml
+++ b/doc/nacos-config/DEFAULT_GROUP/thinglinks-modules-link.yml
@@ -13,4 +13,4 @@ mybatis:
swagger:
title: Link模块接口文档
license: Powered By thinglinks
- licenseUrl: https://showdoc.thinglinks.mqttsnet.com
\ No newline at end of file
+ licenseUrl: http://www.mqttsnet.com/
\ No newline at end of file
diff --git a/doc/nacos-config/DEFAULT_GROUP/thinglinks-modules-rule.yml b/doc/nacos-config/DEFAULT_GROUP/thinglinks-modules-rule.yml
index 0b5eb36d..83698b81 100755
--- a/doc/nacos-config/DEFAULT_GROUP/thinglinks-modules-rule.yml
+++ b/doc/nacos-config/DEFAULT_GROUP/thinglinks-modules-rule.yml
@@ -14,4 +14,4 @@ mybatis:
swagger:
title: Link模块接口文档
license: Powered By thinglinks
- licenseUrl: https://showdoc.thinglinks.mqttsnet.com
\ No newline at end of file
+ licenseUrl: http://www.mqttsnet.com/
\ No newline at end of file
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/device/DeviceCacheVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/device/DeviceCacheVO.java
index f8c8c28d..6d8f2a54 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/device/DeviceCacheVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/device/DeviceCacheVO.java
@@ -25,7 +25,6 @@
@ToString(callSuper = true)
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
-@Builder
@ApiModel(value = "DeviceCacheVO", description = "设备档案缓存VO")
public class DeviceCacheVO extends Device implements Serializable {
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductCacheVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductCacheVO.java
index 2c00f490..1349b55b 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductCacheVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductCacheVO.java
@@ -23,7 +23,6 @@
@ToString(callSuper = true)
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
-@Builder
@ApiModel(value = "ProductCacheVO", description = "产品模型缓存VO")
public class ProductCacheVO extends Product implements Serializable {
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
index 940fe0cb..6d095abd 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
@@ -18,10 +18,9 @@
@Data
@NoArgsConstructor
-@AllArgsConstructor
@ToString(callSuper = true)
@Accessors(chain = true)
-@EqualsAndHashCode
+@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "ProductModelCacheVO", description = "产品模型缓存VO")
public class ProductModelCacheVO extends ProductModel implements Serializable {
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoUpdateSubDeviceStatusParam.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoUpdateSubDeviceStatusParam.java
index 14aa0596..b36a2ec6 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoUpdateSubDeviceStatusParam.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/param/TopoUpdateSubDeviceStatusParam.java
@@ -1,6 +1,6 @@
package com.mqttsnet.thinglinks.link.api.domain.vo.param;
-import com.mqttsnet.thinglinks.device.enumeration.DeviceConnectStatusEnum;
+import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/CacheConstants.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/CacheConstants.java
index 12673b8a..3de55f90 100644
--- a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/CacheConstants.java
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/CacheConstants.java
@@ -42,4 +42,11 @@ public class CacheConstants {
*/
public static final String TDENGINE_SUPERTABLEFILELDS = "tdengine_superTableFields:";
+
+ /**
+ * 设备数据转换脚本 cache key
+ * link-> device_data_reported_agreement_script:deviceIdentification
+ */
+ public static final String DEVICE_DATA_REPORTED_AGREEMENT_SCRIPT = "device_data_reported_agreement_script";
+
}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerGroupConstant.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerGroupConstant.java
index 4d2e1155..99a90555 100644
--- a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerGroupConstant.java
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/mqs/ConsumerGroupConstant.java
@@ -15,5 +15,5 @@ public interface ConsumerGroupConstant {
/**
* default-consumer-group
*/
- String THINGLINKS_GROUP = "thinglinks";
+ String THINGLINKS_GROUP = "thingLinks";
}
diff --git a/thinglinks-modules/thinglinks-modules-link/pom.xml b/thinglinks-modules/thinglinks-modules-link/pom.xml
index ade47d50..ef4bea24 100644
--- a/thinglinks-modules/thinglinks-modules-link/pom.xml
+++ b/thinglinks-modules/thinglinks-modules-link/pom.xml
@@ -73,13 +73,6 @@
${thinglinks.version}
-
-
- com.mqttsnet
- thinglinks-common-kafka
- ${thinglinks.version}
-
-
com.mqttsnet
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
index 1571484e..4e6ace25 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
@@ -1,133 +1,133 @@
-package com.mqttsnet.thinglinks.link.common.cache.service;
-
-import cn.hutool.core.bean.BeanUtil;
-import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
-import com.mqttsnet.thinglinks.common.redis.service.RedisService;
-import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
-import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductCacheVO;
-import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
-import com.mqttsnet.thinglinks.link.common.cache.CacheSuperAbstract;
-import com.mqttsnet.thinglinks.link.service.device.DeviceService;
-import com.mqttsnet.thinglinks.link.service.product.ProductService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-/**
- * -----------------------------------------------------------------------------
- * File Name: DeviceCacheService.java
- * -----------------------------------------------------------------------------
- * Description:
- * Service layer for Device cache management.
- * -----------------------------------------------------------------------------
- *
- * @author ShiHuan Sun
- * @version 1.0
- * -----------------------------------------------------------------------------
- * Revision History:
- * Date Author Version Description
- * -------- -------- ------- --------------------
- *
- * -----------------------------------------------------------------------------
- * @email 13733918655@163.com
- * @date 2023-10-21 22:42
- */
-@Service
-@RequiredArgsConstructor
-@Slf4j
-public class DeviceCacheService extends CacheSuperAbstract {
- private final RedisService redisService;
- private final DeviceService deviceService;
- private final ProductService productService;
-
- /**
- * Refresh the cache with device data for a specific tenant.
- *
- * @param tenantId Identifier of the tenant whose device cache needs to be refreshed.
- */
- public void refreshDeviceCacheForTenant(Long tenantId) {
- int totalDataCount = deviceService.findDeviceTotal().intValue();
- int totalPages = (int) Math.ceil((double) totalDataCount / PAGE_SIZE);
-
- List deviceList = IntStream.range(0, totalPages)
- .mapToObj(currentPage -> {
- Page page = new Page<>(currentPage, PAGE_SIZE);
- Page content = deviceService.page(page, null);
- return Optional.ofNullable(content)
- .map(Page::getRecords)
- .orElse(Collections.emptyList());
- })
- .flatMap(Collection::stream)
- .collect(Collectors.toList());
-
- cacheDevicesForTenant(tenantId, deviceList);
- }
-
- /**
- * Cache a list of devices for a specific tenant.
- *
- * @param tenantId Identifier of the tenant.
- * @param deviceList List of devices to be cached.
- */
- public void cacheDevicesForTenant(Long tenantId, List deviceList) {
- Optional.ofNullable(deviceList)
- .orElse(Collections.emptyList())
- .stream()
- .filter(Objects::nonNull)
- .map(device -> transformToDeviceCacheVO(tenantId, device))
- .filter(Objects::nonNull)
- .forEach(deviceCacheVO -> {
- cacheDeviceBasedOnIdentification(deviceCacheVO);
- cacheDeviceBasedOnClientId(deviceCacheVO);
- });
- }
-
- /**
- * Transforms a device object into a DeviceCacheVO object with associated product data.
- *
- * @param tenantId Identifier of the tenant.
- * @param device Device object to be transformed.
- * @return Transformed DeviceCacheVO object.
- */
- private DeviceCacheVO transformToDeviceCacheVO(Long tenantId, Device device) {
- DeviceCacheVO deviceCacheVO = BeanUtil.toBeanIgnoreError(device, DeviceCacheVO.class);
- deviceCacheVO.setTenantId(tenantId);
-
- Optional.ofNullable(deviceCacheVO.getProductIdentification())
- .map(productService::selectProductByProductIdentificationList)
- .ifPresent(product -> {
- ProductCacheVO productCacheVO = BeanPlusUtil.toBeanIgnoreError(product, ProductCacheVO.class);
- productCacheVO.setTenantId(tenantId);
- deviceCacheVO.setProductCacheVO(productCacheVO);
- });
-
- return deviceCacheVO;
- }
-
- /**
- * Cache the DeviceCacheVO object based on its identification.
- *
- * @param deviceCacheVO DeviceCacheVO object to be cached.
- */
- private void cacheDeviceBasedOnIdentification(DeviceCacheVO deviceCacheVO) {
- CacheKey deviceIdentKey = DeviceCacheKeyBuilder.build(deviceCacheVO.getDeviceIdentification());
- cachePlusOps.del(deviceIdentKey);
- cachePlusOps.set(deviceIdentKey, deviceCacheVO);
- }
-
- /**
- * Cache the DeviceCacheVO object based on its client ID.
- *
- * @param deviceCacheVO DeviceCacheVO object to be cached.
- */
- private void cacheDeviceBasedOnClientId(DeviceCacheVO deviceCacheVO) {
- CacheKey clientIdKey = DeviceCacheKeyBuilder.build(deviceCacheVO.getClientId());
- cachePlusOps.del(clientIdKey);
- cachePlusOps.set(clientIdKey, deviceCacheVO);
- }
-
-}
+//package com.mqttsnet.thinglinks.link.common.cache.service;
+//
+//import cn.hutool.core.bean.BeanUtil;
+//import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
+//import com.mqttsnet.thinglinks.common.redis.service.RedisService;
+//import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
+//import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductCacheVO;
+//import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+//import com.mqttsnet.thinglinks.link.common.cache.CacheSuperAbstract;
+//import com.mqttsnet.thinglinks.link.service.device.DeviceService;
+//import com.mqttsnet.thinglinks.link.service.product.ProductService;
+//import lombok.RequiredArgsConstructor;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.stereotype.Service;
+//
+//import java.util.*;
+//import java.util.stream.Collectors;
+//import java.util.stream.IntStream;
+//
+///**
+// * -----------------------------------------------------------------------------
+// * File Name: DeviceCacheService.java
+// * -----------------------------------------------------------------------------
+// * Description:
+// * Service layer for Device cache management.
+// * -----------------------------------------------------------------------------
+// *
+// * @author ShiHuan Sun
+// * @version 1.0
+// * -----------------------------------------------------------------------------
+// * Revision History:
+// * Date Author Version Description
+// * -------- -------- ------- --------------------
+// *
+// * -----------------------------------------------------------------------------
+// * @email 13733918655@163.com
+// * @date 2023-10-21 22:42
+// */
+//@Service
+//@RequiredArgsConstructor
+//@Slf4j
+//public class DeviceCacheService extends CacheSuperAbstract {
+// private final RedisService redisService;
+// private final DeviceService deviceService;
+// private final ProductService productService;
+//
+// /**
+// * Refresh the cache with device data for a specific tenant.
+// *
+// * @param tenantId Identifier of the tenant whose device cache needs to be refreshed.
+// */
+// public void refreshDeviceCacheForTenant(Long tenantId) {
+// int totalDataCount = deviceService.findDeviceTotal().intValue();
+// int totalPages = (int) Math.ceil((double) totalDataCount / PAGE_SIZE);
+//
+// List deviceList = IntStream.range(0, totalPages)
+// .mapToObj(currentPage -> {
+// Page page = new Page<>(currentPage, PAGE_SIZE);
+// Page content = deviceService.page(page, null);
+// return Optional.ofNullable(content)
+// .map(Page::getRecords)
+// .orElse(Collections.emptyList());
+// })
+// .flatMap(Collection::stream)
+// .collect(Collectors.toList());
+//
+// cacheDevicesForTenant(tenantId, deviceList);
+// }
+//
+// /**
+// * Cache a list of devices for a specific tenant.
+// *
+// * @param tenantId Identifier of the tenant.
+// * @param deviceList List of devices to be cached.
+// */
+// public void cacheDevicesForTenant(Long tenantId, List deviceList) {
+// Optional.ofNullable(deviceList)
+// .orElse(Collections.emptyList())
+// .stream()
+// .filter(Objects::nonNull)
+// .map(device -> transformToDeviceCacheVO(tenantId, device))
+// .filter(Objects::nonNull)
+// .forEach(deviceCacheVO -> {
+// cacheDeviceBasedOnIdentification(deviceCacheVO);
+// cacheDeviceBasedOnClientId(deviceCacheVO);
+// });
+// }
+//
+// /**
+// * Transforms a device object into a DeviceCacheVO object with associated product data.
+// *
+// * @param tenantId Identifier of the tenant.
+// * @param device Device object to be transformed.
+// * @return Transformed DeviceCacheVO object.
+// */
+// private DeviceCacheVO transformToDeviceCacheVO(Long tenantId, Device device) {
+// DeviceCacheVO deviceCacheVO = BeanUtil.toBeanIgnoreError(device, DeviceCacheVO.class);
+// deviceCacheVO.setTenantId(tenantId);
+//
+// Optional.ofNullable(deviceCacheVO.getProductIdentification())
+// .map(productService::selectProductByProductIdentificationList)
+// .ifPresent(product -> {
+// ProductCacheVO productCacheVO = BeanPlusUtil.toBeanIgnoreError(product, ProductCacheVO.class);
+// productCacheVO.setTenantId(tenantId);
+// deviceCacheVO.setProductCacheVO(productCacheVO);
+// });
+//
+// return deviceCacheVO;
+// }
+//
+// /**
+// * Cache the DeviceCacheVO object based on its identification.
+// *
+// * @param deviceCacheVO DeviceCacheVO object to be cached.
+// */
+// private void cacheDeviceBasedOnIdentification(DeviceCacheVO deviceCacheVO) {
+// CacheKey deviceIdentKey = DeviceCacheKeyBuilder.build(deviceCacheVO.getDeviceIdentification());
+// cachePlusOps.del(deviceIdentKey);
+// cachePlusOps.set(deviceIdentKey, deviceCacheVO);
+// }
+//
+// /**
+// * Cache the DeviceCacheVO object based on its client ID.
+// *
+// * @param deviceCacheVO DeviceCacheVO object to be cached.
+// */
+// private void cacheDeviceBasedOnClientId(DeviceCacheVO deviceCacheVO) {
+// CacheKey clientIdKey = DeviceCacheKeyBuilder.build(deviceCacheVO.getClientId());
+// cachePlusOps.del(clientIdKey);
+// cachePlusOps.set(clientIdKey, deviceCacheVO);
+// }
+//
+//}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaConsumerConfig.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaConsumerConfig.java
deleted file mode 100644
index d4df6df5..00000000
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaConsumerConfig.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.mqttsnet.thinglinks.link.common.config;
-
-import org.apache.kafka.clients.consumer.ConsumerConfig;
-import org.apache.kafka.common.serialization.StringDeserializer;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
-import org.springframework.kafka.config.KafkaListenerContainerFactory;
-import org.springframework.kafka.core.ConsumerFactory;
-import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
-import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
-import org.springframework.kafka.listener.ContainerProperties;
-import org.springframework.kafka.support.serializer.JsonDeserializer;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @program: thinglinks
- * @description: KafkaConsumerConfig
- * @packagename: com.mqttsnet.thinglinks.common.kafka.config
- * @author: ShiHuan Sun
- * @e-mainl: 13733918655@163.com
- * @date: 2023-06-18 11:29
- **/
-@Configuration
-public class KafkaConsumerConfig {
-
-
- @Value("${spring.kafka.thingLinks.consumer.bootstrap-servers}")
- private String bootstrapServers;
- @Value("${spring.kafka.thingLinks.consumer.group-id}")
- private String groupId;
- @Value("${spring.kafka.thingLinks.consumer.enable-auto-commit}")
- private boolean enableAutoCommit;
- @Value("${spring.kafka.thingLinks.properties.session.timeout.ms}")
- private String sessionTimeout;
- @Value("${spring.kafka.thingLinks.properties.max.poll.interval.ms}")
- private String maxPollIntervalTime;
- @Value("${spring.kafka.thingLinks.consumer.max-poll-records}")
- private String maxPollRecords;
- @Value("${spring.kafka.thingLinks.consumer.auto-offset-reset}")
- private String autoOffsetReset;
- @Value("${spring.kafka.thingLinks.listener.concurrency}")
- private Integer concurrency;
- @Value("${spring.kafka.thingLinks.listener.missing-topics-fatal}")
- private boolean missingTopicsFatal;
- @Value("${spring.kafka.thingLinks.listener.poll-timeout}")
- private long pollTimeout;
-
- @Bean
- public Map consumerConfigs() {
-
- Map propsMap = new HashMap<>(16);
- propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
- propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
- //是否自动提交偏移量,默认值是true,为了避免出现重复数据和数据丢失,可以把它设置为false,然后手动提交偏移量
- propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit);
- //自动提交的时间间隔,自动提交开启时生效
- propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "2000");
- //该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
- //earliest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费分区的记录
- //latest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据(在消费者启动之后生成的记录)
- //none:当各分区都存在已提交的offset时,从提交的offset开始消费;只要有一个分区不存在已提交的offset,则抛出异常
- propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset);
- //两次poll之间的最大间隔,默认值为5分钟。如果超过这个间隔会触发reBalance
- propsMap.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, maxPollIntervalTime);
- //这个参数定义了poll方法最多可以拉取多少条消息,默认值为500。如果在拉取消息的时候新消息不足500条,那有多少返回多少;如果超过500条,每次只返回500。
- //这个默认值在有些场景下太大,有些场景很难保证能够在5min内处理完500条消息,
- //如果消费者无法在5分钟内处理完500条消息的话就会触发reBalance,
- //然后这批消息会被分配到另一个消费者中,还是会处理不完,这样这批消息就永远也处理不完。
- //要避免出现上述问题,提前评估好处理一条消息最长需要多少时间,然后覆盖默认的max.poll.records参数
- //注:需要开启BatchListener批量监听才会生效,如果不开启BatchListener则不会出现reBalance情况
- propsMap.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, maxPollRecords);
- //当broker多久没有收到consumer的心跳请求后就触发reBalance,默认值是10s
- propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sessionTimeout);
- //序列化(建议使用Json,这种序列化方式可以无需额外配置传输实体类)
- propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
- propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
- return propsMap;
- }
-
- @Bean
- public ConsumerFactory consumerFactory() {
-
- //配置消费者的 Json 反序列化的可信赖包,反序列化实体类需要
- try (StringDeserializer stringDeserializer = new StringDeserializer()) {
- return new DefaultKafkaConsumerFactory<>(consumerConfigs(), new StringDeserializer(), stringDeserializer);
- }
- }
-
- @Bean
- public KafkaListenerContainerFactory> kafkaListenerContainerFactory() {
-
- ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>();
- factory.setConsumerFactory(consumerFactory());
- //在侦听器容器中运行的线程数,一般设置为 机器数*分区数
- factory.setConcurrency(concurrency);
- //消费监听接口监听的主题不存在时,默认会报错,所以设置为false忽略错误
- factory.setMissingTopicsFatal(missingTopicsFatal);
- //自动提交关闭,需要设置手动消息确认
- factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
- factory.getContainerProperties().setPollTimeout(pollTimeout);
- //设置为批量监听,需要用List接收
- factory.setBatchListener(true);
- return factory;
- }
-}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaProviderConfig.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaProviderConfig.java
deleted file mode 100644
index 92fe8016..00000000
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/config/KafkaProviderConfig.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.mqttsnet.thinglinks.link.common.config;
-
-import org.apache.kafka.clients.producer.ProducerConfig;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.kafka.core.DefaultKafkaProducerFactory;
-import org.springframework.kafka.core.KafkaTemplate;
-import org.springframework.kafka.core.ProducerFactory;
-import org.springframework.kafka.support.serializer.JsonSerializer;
-import org.springframework.kafka.transaction.KafkaTransactionManager;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @program: thinglinks
- * @description: KafkaProviderConfig
- * @packagename: com.mqttsnet.thinglinks.common.kafka.config
- * @author: ShiHuan Sun
- * @e-mainl: 13733918655@163.com
- * @date: 2023-06-18 11:28
- **/
-@Configuration
-public class KafkaProviderConfig {
-
-
- @Value("${spring.kafka.thingLinks.producer.bootstrap-servers}")
- private String bootstrapServers;
- @Value("${spring.kafka.thingLinks.producer.transaction-id-prefix}")
- private String transactionIdPrefix;
- @Value("${spring.kafka.thingLinks.producer.acks}")
- private String acks;
- @Value("${spring.kafka.thingLinks.producer.retries}")
- private String retries;
- @Value("${spring.kafka.thingLinks.producer.batch-size}")
- private String batchSize;
- @Value("${spring.kafka.thingLinks.producer.buffer-memory}")
- private String bufferMemory;
-
- @Bean
- public Map producerConfigs() {
-
- Map props = new HashMap<>(16);
- props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
- //acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。
- //acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
- //acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
- //开启事务必须设为all
- props.put(ProducerConfig.ACKS_CONFIG, acks);
- //发生错误后,消息重发的次数,开启事务必须大于0
- props.put(ProducerConfig.RETRIES_CONFIG, retries);
- //当多个消息发送到相同分区时,生产者会将消息打包到一起,以减少请求交互. 而不是一条条发送
- //批次的大小可以通过batch.size 参数设置.默认是16KB
- //较小的批次大小有可能降低吞吐量(批次大小为0则完全禁用批处理)。
- //比如说,kafka里的消息5秒钟Batch才凑满了16KB,才能发送出去。那这些消息的延迟就是5秒钟
- //实测batchSize这个参数没有用
- props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize);
- //有的时刻消息比较少,过了很久,比如5min也没有凑够16KB,这样延时就很大,所以需要一个参数. 再设置一个时间,到了这个时间,
- //即使数据没达到16KB,也将这个批次发送出去
- props.put(ProducerConfig.LINGER_MS_CONFIG, "5000");
- //生产者内存缓冲区的大小
- props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory);
- //反序列化,和生产者的序列化方式对应
- props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
- props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
- return props;
- }
-
- @Bean
- public ProducerFactory producerFactory() {
-
- DefaultKafkaProducerFactory factory = new DefaultKafkaProducerFactory<>(producerConfigs());
- //开启事务,会导致 LINGER_MS_CONFIG 配置失效
- factory.setTransactionIdPrefix(transactionIdPrefix);
- return factory;
- }
-
- @Bean
- public KafkaTransactionManager kafkaTransactionManager(ProducerFactory producerFactory) {
-
- return new KafkaTransactionManager<>(producerFactory);
- }
-
- @Bean
- public KafkaTemplate thingLinksKafkaTemplate() {
-
- return new KafkaTemplate<>(producerFactory());
- }
-}
\ No newline at end of file
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
deleted file mode 100644
index 5b09dc6e..00000000
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/kafka/DeviceActionMessageKafkaConsumer.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.mqttsnet.thinglinks.link.common.consumer.kafka;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.mqttsnet.thinglinks.common.core.enums.MqttEvent;
-import com.mqttsnet.thinglinks.common.kafka.constant.ConsumerKafkaTopicConstant;
-import com.mqttsnet.thinglinks.link.service.device.DeviceActionService;
-import com.mqttsnet.thinglinks.link.service.device.DeviceDatasService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.kafka.annotation.KafkaListener;
-import org.springframework.scheduling.annotation.Async;
-
-import java.util.Objects;
-
-/**
- * @Description: Mqtt动作消息消费(kafka模式)
- * @Author: menffy
- * @E-mail: 13733918655@163.com
- * @Website: http://thinglinks.mqttsnet.com
- * @CreateDate: 2023/08/08
- * @UpdateUser: menffy
- * @UpdateDate: 2023/08/08
- * @UpdateRemark: https://mqttsnet.yuque.com/gt6zkc/thinglinks/yhzgnpduyo8adxgs
- * @Version: 1.0
- */
-@Slf4j
-//@Component
-@Deprecated
-public class DeviceActionMessageKafkaConsumer {
- @Autowired
- private DeviceActionService deviceActionService;
- @Autowired
- private DeviceDatasService deviceDatasService;
-
- @Async("linkAsync")
- @KafkaListener(topics = {
- ConsumerKafkaTopicConstant.THINGLINKS_LINK_MQTT_MSG,
- ConsumerKafkaTopicConstant.THINGLINKS_CLIENT_CONNECTED_TOPIC,
- ConsumerKafkaTopicConstant.THINGLINKS_CLIENT_DISCONNECTED_TOPIC,
- ConsumerKafkaTopicConstant.THINGLINKS_SERVER_CONNECTED_TOPIC,
- ConsumerKafkaTopicConstant.THINGLINKS_DEVICE_KICKED_TOPIC,
- ConsumerKafkaTopicConstant.THINGLINKS_SUBSCRIPTION_ACKED_TOPIC,
- ConsumerKafkaTopicConstant.THINGLINKS_UNSUBSCRIPTION_ACKED_TOPIC,
- ConsumerKafkaTopicConstant.THINGLINKS_DISTRIBUTION_ERROR_TOPIC,
- ConsumerKafkaTopicConstant.THINGLINKS_DISTRIBUTION_COMPLETED_TOPIC})
- public void onMessage(ConsumerRecord, ?> record) {
- if (null == record) {
- log.warn("message cannot be empty {}", record);
- return;
- }
- log.info("ThingLinks物联网平台数据消费-->Received message={}", record);
- JSONObject thinglinksMessage = JSON.parseObject(String.valueOf(record.value()));
- try {
- MqttEvent event = MqttEvent.getMqttEventEnum(thinglinksMessage.get("event").toString());
- switch (Objects.requireNonNull(event)) {
- case CONNECT:
- deviceActionService.insertEvent(thinglinksMessage);
- deviceActionService.connectEvent(thinglinksMessage);
- break;
- case CLOSE:
- case DISCONNECT:
- deviceActionService.insertEvent(thinglinksMessage);
- deviceActionService.closeEvent(thinglinksMessage);
- break;
- case PUBLISH:
- deviceDatasService.insertBaseDatas(thinglinksMessage);
- break;
- case SUBSCRIBE:
- deviceActionService.insertEvent(thinglinksMessage);
- break;
- case UNSUBSCRIBE:
- deviceActionService.insertEvent(thinglinksMessage);
- break;
- case PING:
- deviceActionService.refreshDeviceCache(thinglinksMessage);
- break;
- default:
- }
- } catch (Exception e) {
- log.error("ThingLinks物联网平台数据消费-->消费失败,失败原因:{}", e.getMessage());
- }
- }
-}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
deleted file mode 100644
index 0f0bfbb5..00000000
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/consumer/rocketmq/DeviceActionMessageRocketmqConsumer.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.mqttsnet.thinglinks.link.common.consumer.rocketmq;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.mqttsnet.thinglinks.common.core.enums.MqttEvent;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerGroupConstant;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerTopicConstant;
-import com.mqttsnet.thinglinks.link.service.device.DeviceActionService;
-import com.mqttsnet.thinglinks.link.service.device.DeviceDatasService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.rocketmq.spring.annotation.MessageModel;
-import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
-import org.apache.rocketmq.spring.core.RocketMQListener;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
-
-import java.util.Objects;
-
-/**
- * @Description: Mqtt动作消息消费(Rocketmq模式)
- * @Author: ShiHuan Sun
- * @E-mail: 13733918655@163.com
- * @Website: http://thinglinks.mqttsnet.com
- * @CreateDate: 2021/11/22$ 16:11$
- * @UpdateUser: ShiHuan Sun
- * @UpdateDate: 2021/11/22$ 16:11$
- * @UpdateRemark: 修改内容
- * @Version: 1.0
- */
-@Slf4j
-//@Component
-@Deprecated
-@RocketMQMessageListener(consumerGroup = ConsumerGroupConstant.THINGLINKS_BROKER_GROUP, topic = ConsumerTopicConstant.THINGLINKS_LINK_MQTT_MSG, messageModel = MessageModel.CLUSTERING)
-public class DeviceActionMessageRocketmqConsumer implements RocketMQListener {
- @Autowired
- private DeviceActionService deviceActionService;
- @Autowired
- private DeviceDatasService deviceDatasService;
-
- @Async("linkAsync")
- @Override
- public void onMessage(Object message) {
- if (null == message) {
- log.warn("message cannot be empty {}", message);
- return;
- }
- log.info("ThingLinks物联网平台数据消费-->Received message={}", message);
- JSONObject thinglinksMessage = JSON.parseObject(String.valueOf(message));
- try {
- MqttEvent event = MqttEvent.getMqttEventEnum(thinglinksMessage.get("event").toString());
- switch (Objects.requireNonNull(event)) {
- case CONNECT:
- deviceActionService.insertEvent(thinglinksMessage);
- deviceActionService.connectEvent(thinglinksMessage);
- break;
- case CLOSE:
- case DISCONNECT:
- deviceActionService.insertEvent(thinglinksMessage);
- deviceActionService.closeEvent(thinglinksMessage);
- break;
- case PUBLISH:
- deviceDatasService.insertBaseDatas(thinglinksMessage);
- break;
- case SUBSCRIBE:
- deviceActionService.insertEvent(thinglinksMessage);
- break;
- case UNSUBSCRIBE:
- deviceActionService.insertEvent(thinglinksMessage);
- break;
- case PING:
- deviceActionService.refreshDeviceCache(thinglinksMessage);
- break;
- default:
- }
- } catch (Exception e) {
- log.error("ThingLinks物联网平台数据消费-->消费失败,失败原因:{}", e.getMessage());
- }
- }
-}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
index b6e0436d..194834c3 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
@@ -14,10 +14,7 @@
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
import com.mqttsnet.thinglinks.link.api.domain.device.model.DeviceParams;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
-import com.mqttsnet.thinglinks.link.api.domain.vo.param.OtaCommandResponseParam;
-import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoAddSubDeviceParam;
-import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoQueryDeviceParam;
-import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoUpdateSubDeviceStatusParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
@@ -26,7 +23,7 @@
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@@ -446,10 +443,10 @@ public R queryDeviceByHttp(@RequestBody TopoQueryDevice
public R saveOtaUpgradeRecordByMqtt(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam) {
try {
// Call the service method to save the record
- OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveOtaUpgradeRecordByMqtt(otaCommandResponseParam);
+// OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveOtaUpgradeRecordByMqtt(otaCommandResponseParam);
// Return a successful response entity with the saved record
- return R.ok(savedRecord);
+ return R.ok();
} catch (Exception e) {
// Log the exception and return an error response entity
// Assuming R.fail() is a method to create a failure response
@@ -469,10 +466,10 @@ public R saveOtaUpgradeRecordByMqtt(@Valid @RequestBody
public R saveUpgradeRecordByHttp(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam) {
try {
// Call the service method to save the record
- OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveUpgradeRecordByHttp(otaCommandResponseParam);
+// OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveUpgradeRecordByHttp(otaCommandResponseParam);
// Return a successful response wrapper with the saved record
- return R.ok(savedRecord);
+ return R.ok();
} catch (Exception e) {
// Log the exception and return a failure response wrapper
// Assuming R.fail() is a method to create a failure response
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/kafka/KafkaController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/kafka/KafkaController.java
deleted file mode 100644
index 3715d1d6..00000000
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/kafka/KafkaController.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.mqttsnet.thinglinks.link.controller.kafka;
-
-import org.apache.kafka.clients.producer.ProducerRecord;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.kafka.core.KafkaTemplate;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.Map;
-
-/**
- * @Description: kafka接口
- * @Author: ShiHuan Sun
- * @E-mail: 13733918655@163.com
- * @Website: http://thinglinks.mqttsnet.com
- * @CreateDate: 2021/12/1$ 11:39$
- * @UpdateUser: ShiHuan Sun
- * @UpdateDate: 2021/12/1$ 11:39$
- * @UpdateRemark: 修改内容
- * @Version: 1.0
- */
-@RestController
-@RequestMapping("/kafkaMessage")
-public class KafkaController {
-
- @Autowired
- KafkaTemplate thingLinksProKafkaTemplate;
-
- @Transactional
- @PostMapping("/send")
- public String kafkaMessageSend(@RequestBody Map params) {
- thingLinksProKafkaTemplate.send(new ProducerRecord<>(String.valueOf(params.get("topic")), String.valueOf(params.get("msg"))));
- return "success-" + params.get("topic");
- }
-}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/DeviceService.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/DeviceService.java
index 222f89df..be2835d1 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/DeviceService.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/DeviceService.java
@@ -1,8 +1,11 @@
package com.mqttsnet.thinglinks.link.service.device;
-import com.mqttsnet.thinglinks.common.core.web.page.TableDataInfo;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
import com.mqttsnet.thinglinks.link.api.domain.device.model.DeviceParams;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
import java.util.Collection;
import java.util.List;
@@ -162,7 +165,7 @@ public interface DeviceService {
List findAllByProductIdentification(String productIdentification);
- Device selectByProductIdentificationAndDeviceIdentification(String productIdentification,String deviceIdentification);
+ Device selectByProductIdentificationAndDeviceIdentification(String productIdentification, String deviceIdentification);
/**
* 查询设备详细信息
@@ -175,14 +178,97 @@ public interface DeviceService {
/**
* 查询普通设备影子数据
*
- * @param ids 需要查询的普通设备id
+ * @param ids 需要查询的普通设备id
* @param startTime 开始时间 格式:yyyy-MM-dd HH:mm:ss
- * @param endTime 结束时间 格式:yyyy-MM-dd HH:mm:ss
+ * @param endTime 结束时间 格式:yyyy-MM-dd HH:mm:ss
* @return 普通设备影子数据
*/
public Map>> getDeviceShadow(String ids, String startTime, String endTime);
- public List selectDeviceByDeviceIdentificationList( List deviceIdentificationList);
+ public List selectDeviceByDeviceIdentificationList(List deviceIdentificationList);
+
+ /**
+ * MQTT协议下添加子设备
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 添加结果
+ */
+ TopoAddDeviceResultVO saveSubDeviceByMqtt(TopoAddSubDeviceParam topoAddSubDeviceParam);
+
+ /**
+ * HTTP协议下添加子设备
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 添加结果
+ */
+ TopoAddDeviceResultVO saveSubDeviceByHttp(TopoAddSubDeviceParam topoAddSubDeviceParam);
+
+ /**
+ * MQTT协议下更新子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 更新参数
+ * @return {@link TopoDeviceOperationResultVO} 更新结果
+ */
+ TopoDeviceOperationResultVO updateSubDeviceConnectStatusByMqtt(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam);
+
+ /**
+ * Http协议下更新子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 更新参数
+ * @return {@link TopoDeviceOperationResultVO} 更新结果
+ */
+ TopoDeviceOperationResultVO updateSubDeviceConnectStatusByHttp(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam);
+
+ /**
+ * MQTT协议下删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 删除结果
+ */
+ TopoDeviceOperationResultVO deleteSubDeviceByMqtt(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam);
+
+
+ /**
+ * Http协议下删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 删除结果
+ */
+ TopoDeviceOperationResultVO deleteSubDeviceByHttp(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam);
+
+ /**
+ * MQTT协议下上报设备数据
+ *
+ * @param topoDeviceDataReportParam 上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ TopoDeviceOperationResultVO deviceDataReportByMqtt(TopoDeviceDataReportParam topoDeviceDataReportParam);
+
+
+ /**
+ * Http协议下上报设备数据
+ *
+ * @param topoDeviceDataReportParam 上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ TopoDeviceOperationResultVO deviceDataReportByHttp(TopoDeviceDataReportParam topoDeviceDataReportParam);
+
+
+ /**
+ * Queries device information using the MQTT protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ TopoQueryDeviceResultVO queryDeviceByMqtt(TopoQueryDeviceParam topoQueryDeviceParam);
+
+ /**
+ * Queries device information using the HTTP protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ TopoQueryDeviceResultVO queryDeviceByHttp(TopoQueryDeviceParam topoQueryDeviceParam);
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceActionServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceActionServiceImpl.java
index 294b09de..e181f6a3 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceActionServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceActionServiceImpl.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
+import com.mqttsnet.thinglinks.common.core.constant.CacheConstants;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatusEnum;
import com.mqttsnet.thinglinks.common.core.utils.DateUtils;
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceServiceImpl.java
index 8e0ce933..46f3bdb0 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/device/impl/DeviceServiceImpl.java
@@ -19,6 +19,10 @@
import com.mqttsnet.thinglinks.link.api.domain.device.model.DeviceParams;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.ProductServices;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
import com.mqttsnet.thinglinks.link.mapper.device.DeviceMapper;
import com.mqttsnet.thinglinks.link.service.device.DeviceLocationService;
import com.mqttsnet.thinglinks.link.service.device.DeviceService;
@@ -557,5 +561,115 @@ public Boolean createCommonDeviceTDSubtable(Device device) {
public List selectDeviceByDeviceIdentificationList(List deviceIdentificationList) {
return deviceMapper.selectDeviceByDeviceIdentificationList(deviceIdentificationList);
}
+
+ /**
+ * MQTT协议下添加子设备
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 添加结果
+ */
+ @Override
+ public TopoAddDeviceResultVO saveSubDeviceByMqtt(TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return null;
+ }
+
+ /**
+ * HTTP协议下添加子设备
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 添加结果
+ */
+ @Override
+ public TopoAddDeviceResultVO saveSubDeviceByHttp(TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return null;
+ }
+
+ /**
+ * MQTT协议下更新子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 更新参数
+ * @return {@link TopoDeviceOperationResultVO} 更新结果
+ */
+ @Override
+ public TopoDeviceOperationResultVO updateSubDeviceConnectStatusByMqtt(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ return null;
+ }
+
+ /**
+ * Http协议下更新子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 更新参数
+ * @return {@link TopoDeviceOperationResultVO} 更新结果
+ */
+ @Override
+ public TopoDeviceOperationResultVO updateSubDeviceConnectStatusByHttp(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ return null;
+ }
+
+ /**
+ * MQTT协议下删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 删除结果
+ */
+ @Override
+ public TopoDeviceOperationResultVO deleteSubDeviceByMqtt(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ return null;
+ }
+
+ /**
+ * Http协议下删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 删除结果
+ */
+ @Override
+ public TopoDeviceOperationResultVO deleteSubDeviceByHttp(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ return null;
+ }
+
+ /**
+ * MQTT协议下上报设备数据
+ *
+ * @param topoDeviceDataReportParam 上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @Override
+ public TopoDeviceOperationResultVO deviceDataReportByMqtt(TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ return null;
+ }
+
+ /**
+ * Http协议下上报设备数据
+ *
+ * @param topoDeviceDataReportParam 上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @Override
+ public TopoDeviceOperationResultVO deviceDataReportByHttp(TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ return null;
+ }
+
+ /**
+ * Queries device information using the MQTT protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @Override
+ public TopoQueryDeviceResultVO queryDeviceByMqtt(TopoQueryDeviceParam topoQueryDeviceParam) {
+ return null;
+ }
+
+ /**
+ * Queries device information using the HTTP protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @Override
+ public TopoQueryDeviceResultVO queryDeviceByHttp(TopoQueryDeviceParam topoQueryDeviceParam) {
+ return null;
+ }
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
index ba4f3e3c..4b44f868 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/product/impl/ProductServiceImpl.java
@@ -16,8 +16,6 @@
import com.mqttsnet.thinglinks.common.core.utils.bean.BeanUtils;
import com.mqttsnet.thinglinks.common.core.web.domain.AjaxResult;
import com.mqttsnet.thinglinks.common.redis.service.RedisService;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerTopicConstant;
-import com.mqttsnet.thinglinks.common.rocketmq.domain.MQMessage;
import com.mqttsnet.thinglinks.common.security.service.TokenService;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.ProductProperties;
@@ -35,7 +33,6 @@
import com.mqttsnet.thinglinks.tdengine.api.domain.Fields;
import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDto;
import lombok.extern.slf4j.Slf4j;
-import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
@@ -82,8 +79,6 @@ public class ProductServiceImpl implements ProductService {
private RemoteTdEngineService remoteTdEngineService;
@Autowired
private RedisService redisService;
- @Autowired
- private RocketMQTemplate rocketMQTemplate;
/**
* 数据库名称
@@ -658,15 +653,15 @@ public List createSuperTableDataModel(Long[] productIds, Boolean
log.info("缓存超级表数据模型:{}", JSON.toJSONString(superTableDto));
superTableDtoList.add(superTableDto);
if (Boolean.TRUE.equals(InitializeOrNot)) {
- //推送RocketMq消息初始化超级表
- MQMessage mqMessage = new MQMessage();
+ //推送RocketMq消息初始化超级表 TODO 改为API调用
+ /*MQMessage mqMessage = new MQMessage();
mqMessage.setTopic(ConsumerTopicConstant.PRODUCTSUPERTABLE_CREATEORUPDATE);
final JSONObject jsonObject = new JSONObject();
jsonObject.put("type", "create");
jsonObject.put("msg", JSON.toJSONString(superTableDto));
mqMessage.setMessage(jsonObject.toJSONString());
- rocketMQTemplate.convertAndSend(mqMessage.getTopic(), mqMessage.getMessage());
+ rocketMQTemplate.convertAndSend(mqMessage.getTopic(), mqMessage.getMessage());*/
}
}
}
diff --git a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/service/impl/RuleDeviceLinkageServiceImpl.java b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/service/impl/RuleDeviceLinkageServiceImpl.java
index 78cf36e0..8263258b 100644
--- a/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/service/impl/RuleDeviceLinkageServiceImpl.java
+++ b/thinglinks-modules/thinglinks-modules-rule/src/main/java/com/mqttsnet/thinglinks/rule/service/impl/RuleDeviceLinkageServiceImpl.java
@@ -7,8 +7,8 @@
import com.mqttsnet.thinglinks.common.core.enums.FieldTypeEnum;
import com.mqttsnet.thinglinks.common.core.enums.OperatorEnum;
import com.mqttsnet.thinglinks.common.core.enums.TriggeringEnum;
+import com.mqttsnet.thinglinks.common.core.mqs.ConsumerTopicConstant;
import com.mqttsnet.thinglinks.common.core.utils.CompareUtil;
-import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerTopicConstant;
import com.mqttsnet.thinglinks.common.rocketmq.domain.MQMessage;
import com.mqttsnet.thinglinks.link.api.*;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
@@ -90,7 +90,7 @@ public class RuleDeviceLinkageServiceImpl implements RuleDeviceLinkageService {
@Transactional
public void triggerDeviceLinkageByRuleIdentification(String ruleIdentification) {
MQMessage mqMessage = new MQMessage();
- mqMessage.setTopic(ConsumerTopicConstant.THINGLINKS_RULE_TRIGGER);
+ mqMessage.setTopic(ConsumerTopicConstant.Rule.THINGLINKS_RULE_TRIGGER);
JSONObject jsonObject = new JSONObject();
jsonObject.put("msg", ruleIdentification);
mqMessage.setMessage(jsonObject.toJSONString());
diff --git a/thinglinks-modules/thinglinks-modules-rule/src/main/resources/bootstrap.yml b/thinglinks-modules/thinglinks-modules-rule/src/main/resources/bootstrap.yml
index 4a9af6db..34e7f925 100644
--- a/thinglinks-modules/thinglinks-modules-rule/src/main/resources/bootstrap.yml
+++ b/thinglinks-modules/thinglinks-modules-rule/src/main/resources/bootstrap.yml
@@ -33,7 +33,7 @@ spring:
refresh: false
- dataId: database.yml
refresh: true
- - dataId: kafka.yml
+ - dataId: rocketmq.yml
refresh: false
username: @nacos.username@
password: @nacos.password@
\ No newline at end of file
From fe55dddb7aa22bb47354703236bbd50d50eb5b67 Mon Sep 17 00:00:00 2001
From: wangfan1997 <1624212366@qq.com>
Date: Sat, 16 Mar 2024 00:11:36 +0800
Subject: [PATCH 09/35] =?UTF-8?q?add=20ota=E5=9F=BA=E6=9C=AC=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
doc/sql/changeRecord/1.2.0.RELEASE.sql | 12 +-
.../cache/product/ProductModelCacheVO.java | 5 +
.../thinglinks-modules-link/pom.xml | 4 +
.../link/ThingLinksLinkApplication.java | 13 +-
.../cache/service/DeviceCacheService.java | 6 +-
.../ota/OtaUpgradeRecordsController.java | 102 +++++++++++
.../ota/OtaUpgradeTasksController.java | 91 ++++++++++
.../controller/ota/OtaUpgradesController.java | 77 ++++++++
.../mapper/ota/OtaUpgradeRecordsMapper.java | 24 +++
.../mapper/ota/OtaUpgradeTasksMapper.java | 31 ++++
.../link/mapper/ota/OtaUpgradesMapper.java | 29 +++
.../service/ota/OtaUpgradeRecordsService.java | 40 +++++
.../service/ota/OtaUpgradeTasksService.java | 61 +++++++
.../link/service/ota/OtaUpgradesService.java | 33 ++++
.../impl/OtaUpgradeRecordsServiceImpl.java | 108 +++++++++++
.../ota/impl/OtaUpgradeTasksServiceImpl.java | 169 ++++++++++++++++++
.../ota/impl/OtaUpgradesServiceImpl.java | 145 +++++++++++++++
.../link/ota/OtaUpgradeRecordsMapper.xml | 69 +++++++
.../mapper/link/ota/OtaUpgradeTasksMapper.xml | 66 +++++++
.../mapper/link/ota/OtaUpgradesMapper.xml | 156 ++++++++++++++++
20 files changed, 1232 insertions(+), 9 deletions(-)
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradeRecordsController.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradeTasksController.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradesController.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradeRecordsMapper.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradeTasksMapper.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradesMapper.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradeRecordsService.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradeTasksService.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradesService.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradeRecordsServiceImpl.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradeTasksServiceImpl.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradesServiceImpl.java
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradeRecordsMapper.xml
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradeTasksMapper.xml
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradesMapper.xml
diff --git a/doc/sql/changeRecord/1.2.0.RELEASE.sql b/doc/sql/changeRecord/1.2.0.RELEASE.sql
index ccdad5f8..79f0ebd2 100644
--- a/doc/sql/changeRecord/1.2.0.RELEASE.sql
+++ b/doc/sql/changeRecord/1.2.0.RELEASE.sql
@@ -22,9 +22,9 @@ CREATE TABLE `ota_upgrades`
`description` varchar(255) DEFAULT '' COMMENT '升级包功能描述',
`custom_info` longtext COMMENT '自定义信息',
`remark` varchar(255) DEFAULT '' COMMENT '描述',
- `created_by` bigint(20) DEFAULT NULL COMMENT '创建人',
+ `created_by` varchar(20) DEFAULT NULL COMMENT '创建人',
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `updated_by` bigint(20) DEFAULT NULL COMMENT '更新人',
+ `updated_by` varchar(20) DEFAULT NULL COMMENT '更新人',
`updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_app_id` (`app_id`) USING BTREE COMMENT '应用ID',
@@ -41,9 +41,9 @@ CREATE TABLE `ota_upgrade_tasks`
`scheduled_time` datetime DEFAULT NULL COMMENT '计划执行时间',
`description` varchar(255) DEFAULT '' COMMENT '任务描述',
`remark` varchar(255) DEFAULT '' COMMENT '描述',
- `created_by` bigint(20) DEFAULT NULL COMMENT '创建人',
+ `created_by` varchar(20) DEFAULT NULL COMMENT '创建人',
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `updated_by` bigint(20) DEFAULT NULL COMMENT '更新人',
+ `updated_by` varchar(20) DEFAULT NULL COMMENT '更新人',
`updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_upgrade_id` (`upgrade_id`) USING BTREE COMMENT '升级包ID'
@@ -64,9 +64,9 @@ CREATE TABLE `ota_upgrade_records`
`failure_details` longtext COMMENT '升级失败详细信息',
`log_details` longtext COMMENT '升级过程日志',
`remark` varchar(255) DEFAULT '' COMMENT '描述',
- `created_by` bigint(20) DEFAULT NULL COMMENT '创建人',
+ `created_by` varchar(20) DEFAULT NULL COMMENT '创建人',
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
- `updated_by` bigint(20) DEFAULT NULL COMMENT '更新人',
+ `updated_by` varchar(20) DEFAULT NULL COMMENT '更新人',
`updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `idx_task_id_device_identification` (`task_id`,`device_identification`) USING BTREE,
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
index 6d095abd..38fcd65b 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
@@ -1,11 +1,13 @@
package com.mqttsnet.thinglinks.link.api.domain.cache.product;
+import cn.hutool.core.map.MapUtil;
import com.mqttsnet.thinglinks.link.api.domain.product.model.ProductModel;
import io.swagger.annotations.ApiModel;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
+import java.util.Map;
/**
*
@@ -22,7 +24,10 @@
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Builder
+@AllArgsConstructor
@ApiModel(value = "ProductModelCacheVO", description = "产品模型缓存VO")
public class ProductModelCacheVO extends ProductModel implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private Map echoMap = MapUtil.newHashMap();
}
diff --git a/thinglinks-modules/thinglinks-modules-link/pom.xml b/thinglinks-modules/thinglinks-modules-link/pom.xml
index ef4bea24..6f907f4f 100644
--- a/thinglinks-modules/thinglinks-modules-link/pom.xml
+++ b/thinglinks-modules/thinglinks-modules-link/pom.xml
@@ -93,6 +93,10 @@
thinglinks-api-broker
${thinglinks.version}
+
+ commons-collections
+ commons-collections
+
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/ThingLinksLinkApplication.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/ThingLinksLinkApplication.java
index a1653902..dd2e7f16 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/ThingLinksLinkApplication.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/ThingLinksLinkApplication.java
@@ -3,10 +3,15 @@
import com.mqttsnet.thinglinks.common.security.annotation.EnableCustomConfig;
import com.mqttsnet.thinglinks.common.security.annotation.EnableRyFeignClients;
import com.mqttsnet.thinglinks.common.swagger.annotation.EnableCustomSwagger2;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.CrossOrigin;
+import java.net.InetAddress;
+
/**
* Link
*
@@ -20,11 +25,15 @@
//maxAge飞行前响应的缓存持续时间的最大年龄,简单来说就是Cookie的有效期 单位为秒
//若maxAge是负数,则代表为临时Cookie,不会被持久化,Cookie信息保存在浏览器内存中,浏览器关闭Cookie就消失
@CrossOrigin(origins = "*", maxAge = 3600)
+@Slf4j
@SpringBootApplication(scanBasePackages = {"com.mqttsnet.thinglinks"})
public class ThingLinksLinkApplication {
public static void main(String[] args) throws Exception {
- SpringApplication.run(ThingLinksLinkApplication.class, args);
- System.out.println("(♥◠‿◠)ノ゙ Link模块启动成功 ლ(´ڡ`ლ)゙ ");
+ ConfigurableApplicationContext application = SpringApplication.run(ThingLinksLinkApplication.class, args);
+ Environment env = application.getEnvironment();
+ log.info("\n----------------------------------------------------------\n\t" + "应用 '{}' 启动成功! 访问连接:\n\t" + "Swagger文档: \t\thttp://{}:{}/swagger-ui.html\n\t"
+ + "数据库监控: \t\thttp://{}:{}/druid\n" + "----------------------------------------------------------", env.getProperty("spring.application.name"),
+ InetAddress.getLocalHost().getHostAddress(), env.getProperty("server.port", "8080"), "127.0.0.1", env.getProperty("server.port", "8080"));
}
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
index 4e6ace25..a477ba86 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/common/cache/service/DeviceCacheService.java
@@ -11,6 +11,7 @@
//import com.mqttsnet.thinglinks.link.service.product.ProductService;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
+//import org.apache.ibatis.cache.CacheKey;
//import org.springframework.stereotype.Service;
//
//import java.util.*;
@@ -56,7 +57,10 @@
// List deviceList = IntStream.range(0, totalPages)
// .mapToObj(currentPage -> {
// Page page = new Page<>(currentPage, PAGE_SIZE);
-// Page content = deviceService.page(page, null);
+// HashMap pageHashMap = new HashMap<>();
+// Device device = new Device();
+// device.setParams(pageHashMap);
+// Page content = deviceService.findPageAll(page, null);
// return Optional.ofNullable(content)
// .map(Page::getRecords)
// .orElse(Collections.emptyList());
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradeRecordsController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradeRecordsController.java
new file mode 100644
index 00000000..4ff781bb
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradeRecordsController.java
@@ -0,0 +1,102 @@
+package com.mqttsnet.thinglinks.link.controller.ota;
+
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.web.controller.BaseController;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradeRecordsSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradeRecordsUpdateVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.OtaCommandResponseParam;
+import com.mqttsnet.thinglinks.link.service.ota.OtaUpgradeRecordsService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+/**
+ *
+ * 前端控制器
+ * OTA升级记录表
+ *
+ *
+ * @author mqttsnet
+ * @date 2024-01-12 22:42:04
+ * @create [2024-01-12 22:42:04] [mqttsnet]
+ */
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("/otaUpgradeRecords")
+@Api(value = "OtaUpgradeRecords", tags = "OTA升级记录表")
+public class OtaUpgradeRecordsController extends BaseController {
+
+ @Resource
+ private OtaUpgradeRecordsService otaUpgradeRecordsService;
+
+ @ApiOperation(value = "保存OTA升级记录", httpMethod = "POST", notes = "保存一个新的OTA升级记录")
+ @PostMapping("/saveOtaUpgradeRecord")
+ public R saveOtaUpgradeRecord(@Valid @RequestBody OtaUpgradeRecordsSaveVO saveVO) {
+ // 从服务中保存OTA升级记录
+ OtaUpgradeRecordsSaveVO savedRecord = otaUpgradeRecordsService.saveOtaUpgradeRecord(saveVO);
+ // 返回成功响应实体,包含已保存的记录
+ return R.ok(savedRecord);
+ }
+
+ @ApiOperation(value = "更新OTA升级记录", httpMethod = "PUT", notes = "更新一个现有的OTA升级记录")
+ @PutMapping("/updateOtaUpgradeRecord")
+ public R updateOtaUpgradeRecord(@Valid @RequestBody OtaUpgradeRecordsUpdateVO updateVO) {
+ // 从服务中更新OTA升级记录
+ OtaUpgradeRecordsUpdateVO updatedRecord = otaUpgradeRecordsService.updateOtaUpgradeRecord(updateVO);
+ // 返回成功响应实体,包含已更新的记录
+ return R.ok(updatedRecord);
+ }
+
+ /**
+ * 从MQTT消息接收并保存新的OTA升级记录。此端点
+ * 从MQTT消息体捕获命令响应参数并持久化它们。
+ *
+ * @param otaCommandResponseParam 来自通过MQTT发送的OTA命令的响应参数。
+ * @return {@link R< OtaCommandResponseParam >} 包含已保存OTA升级记录的响应实体。
+ */
+ @ApiOperation(value = "保存OTA升级记录", httpMethod = "POST", notes = "从MQTT消息数据保存一个新的OTA升级记录。")
+ @PostMapping("/saveOtaUpgradeRecordByMqtt")
+ public R saveOtaUpgradeRecordByMqtt(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam) {
+ try {
+ // 调用服务方法保存记录
+ OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveOtaUpgradeRecordByMqtt(otaCommandResponseParam);
+ // 返回包含已保存记录的成功响应实体
+ return R.ok(savedRecord);
+ } catch (Exception e) {
+ // 记录异常并返回错误响应实体
+ return R.fail("保存OTA升级记录时出错: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 从HTTP请求接收并保存新的OTA升级记录。此端点
+ * 从请求体捕获命令响应参数并持久化它们。
+ *
+ * @param otaCommandResponseParam 来自通过HTTP发送的OTA命令的响应参数。
+ * @return {@link R} 包含已保存OTA升级记录的响应包装器。
+ */
+ @ApiOperation(value = "通过HTTP保存OTA升级记录", httpMethod = "POST", notes = "从HTTP请求数据保存一个新的OTA升级记录。")
+ @PostMapping("/saveUpgradeRecordByHttp")
+ public R saveUpgradeRecordByHttp(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam) {
+ try {
+ // 调用服务方法保存记录
+ OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveUpgradeRecordByHttp(otaCommandResponseParam);
+ // 返回包含已保存记录的成功响应包装器
+ return R.ok(savedRecord);
+ } catch (Exception e) {
+ // 记录异常并返回失败响应包装器
+ return R.fail("通过HTTP保存OTA升级记录时出错: " + e.getMessage());
+ }
+ }
+
+
+
+}
+
+
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradeTasksController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradeTasksController.java
new file mode 100644
index 00000000..53972a0f
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradeTasksController.java
@@ -0,0 +1,91 @@
+package com.mqttsnet.thinglinks.link.controller.ota;
+
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.web.controller.BaseController;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.result.OtaUpgradeTasksResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradeTasksSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradeTasksUpdateVO;
+import com.mqttsnet.thinglinks.link.service.ota.OtaUpgradeTasksService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.time.LocalDateTime;
+import java.util.List;
+@Validated
+@RestController
+@RequestMapping("/otaUpgradeTasks")
+@Api(value = "OtaUpgradeTasks", tags = "OTA升级任务表")
+@Slf4j
+public class OtaUpgradeTasksController extends BaseController {
+
+ @Resource
+ private OtaUpgradeTasksService otaUpgradeTasksService;
+
+ @ApiOperation(value = "保存OTA升级任务", httpMethod = "POST", notes = "保存一个新的OTA升级任务")
+ @PostMapping("/saveUpgradeTask")
+ public R saveUpgradeTask(@Valid @RequestBody OtaUpgradeTasksSaveVO saveVO) {
+ OtaUpgradeTasksSaveVO saveUpgradeTask = otaUpgradeTasksService.saveUpgradeTask(saveVO);
+ return R.ok(saveUpgradeTask);
+ }
+
+ @ApiOperation(value = "更新OTA升级任务", httpMethod = "PUT", notes = "更新一个现有的OTA升级任务")
+ @PutMapping("/updateUpgradeTask")
+ public R updateUpgradeTask(@Valid @RequestBody OtaUpgradeTasksUpdateVO updateVO) {
+ OtaUpgradeTasksUpdateVO updatedTaskVO = otaUpgradeTasksService.updateUpgradeTask(updateVO);
+ return R.ok(updatedTaskVO);
+ }
+
+ @ApiOperation(value = "更改OTA升级任务状态", httpMethod = "PUT", notes = "更改OTA升级任务的状态")
+ @PutMapping("/changeTaskStatus/{id}")
+ public R changeTaskStatus(
+ @ApiParam(value = "任务ID", required = true) @PathVariable("id") Long id,
+ @ApiParam(value = "新任务状态(0:待处理,1:进行中,2:已完成,3:已取消)", required = true, allowableValues = "0,1,2,3") @RequestParam("status") Integer status) {
+ log.info("更改任务状态 id:{}, 状态:{}", id, status);
+ return R.ok(otaUpgradeTasksService.changeTaskStatus(id, status));
+ }
+
+ @ApiOperation(value = "删除OTA升级任务", httpMethod = "DELETE", notes = "通过其ID删除OTA升级任务")
+ @DeleteMapping("/deleteOtaUpgradeTask/{id}")
+ public R deleteOtaUpgradeTask(@ApiParam(value = "OTA升级任务ID", required = true) @PathVariable("id") Long id) {
+ log.info("删除OTA升级任务 id: {}", id);
+ return R.ok(otaUpgradeTasksService.deleteOtaUpgradeTask(id));
+ }
+
+ @ApiOperation(value = "批量删除OTA升级任务", httpMethod = "DELETE", notes = "通过它们的ID批量删除OTA升级任务")
+ @DeleteMapping("/deleteOtaUpgradeTasks")
+ public R deleteOtaUpgradeTasks(@ApiParam(value = "OTA升级任务ID", required = true) @RequestBody List ids) {
+ log.info("批量删除OTA升级任务 ids: {}", ids);
+ boolean allDeleted = ids.stream().distinct().allMatch(id -> otaUpgradeTasksService.deleteOtaUpgradeTask(id));
+ return R.ok(allDeleted);
+ }
+
+ /**
+ * 根据其ID获取OTA升级任务的详细信息,包括相关升级包信息。
+ *
+ * @param id 要检索的OTA升级任务的ID。
+ * @return {@link OtaUpgradeTasksResultVO} OTA升级任务的详细信息。
+ */
+ @ApiOperation(value = "获取OTA升级任务详情", httpMethod = "GET", notes = "通过ID检索OTA升级任务的详细信息。")
+ @GetMapping("/details/{id}")
+ public R getUpgradeTaskDetails(@ApiParam(value = "OTA升级任务的唯一标识符。", required = true) @PathVariable Long id) {
+ return R.ok(otaUpgradeTasksService.getUpgradeTaskDetails(id));
+ }
+ /**
+ * 根据开始时间及结束时间执行ota升级任务,包括相关升级包信息。
+ *
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return {@link OtaUpgradeTasksResultVO} OTA升级任务的详细信息。
+ */
+ @ApiOperation(value = " OTA远程升级", httpMethod = "GET", notes = "根据开始时间及结束时间执行ota升级任务,包括相关升级包信息。。")
+ @GetMapping("/upgrade")
+ public R> otaUpgradeTasksExecute(@RequestParam("startTime") LocalDateTime startTime, @RequestParam("endTime") LocalDateTime endTime) {
+ return R.ok(otaUpgradeTasksService.otaUpgradeTasksExecute(startTime, endTime));
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradesController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradesController.java
new file mode 100644
index 00000000..857b4c3b
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/ota/OtaUpgradesController.java
@@ -0,0 +1,77 @@
+package com.mqttsnet.thinglinks.link.controller.ota;
+
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.web.controller.BaseController;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradesSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradesUpdateVO;
+import com.mqttsnet.thinglinks.link.service.ota.OtaUpgradesService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+@Validated
+@RestController
+@RequestMapping("/otaUpgrades")
+@Api(value = "OtaUpgrades", tags = "OTA升级包")
+@Slf4j
+public class OtaUpgradesController extends BaseController {
+ /**
+ * 服务对象
+ */
+ @Resource
+ private OtaUpgradesService otaUpgradesService;
+
+ @ApiOperation(value = "保存OTA升级包", httpMethod = "POST", notes = "保存一个新的OTA升级包")
+ @PostMapping("/saveUpgradePackage")
+ public R saveUpgradePackage(@Valid @RequestBody OtaUpgradesSaveVO saveVO) {
+ // 从服务中保存OTA升级包
+ OtaUpgradesSaveVO createdSaveVO = otaUpgradesService.saveUpgradePackage(saveVO);
+ return R.ok(createdSaveVO);
+ }
+
+ @ApiOperation(value = "更新OTA升级包", httpMethod = "PUT", notes = "更新一个现有的OTA升级包")
+ @PutMapping("/updateUpgradePackage")
+ public R> updateUpgradePackage(@Valid @RequestBody OtaUpgradesUpdateVO updateVO) {
+ // 从服务中保存OTA升级包
+ OtaUpgradesUpdateVO otaUpgradesUpdateVO = otaUpgradesService.updateUpgradePackage(updateVO);
+ return R.ok(otaUpgradesUpdateVO);
+ }
+
+ @ApiOperation(value = "更新OTA升级包状态", httpMethod = "PUT", notes = "更新OTA升级包的状态")
+ @PutMapping("/updateOtaUpgradeStatus/{id}")
+ public R updateOtaUpgradeStatus(
+ @ApiParam(value = "包ID", required = true) @PathVariable("id") Long id,
+ @ApiParam(value = "新状态值(1:启用,-1:禁用)", required = true) @RequestParam("status") Integer status) {
+ // 记录信息
+ log.info("更新OTA升级状态 id:{}, 状态:{}", id, status);
+ // 返回更新状态的成功响应
+ return R.ok(otaUpgradesService.updateOtaUpgradeStatus(id, status));
+ }
+
+ @ApiOperation(value = "删除OTA升级包", httpMethod = "DELETE", notes = "通过其ID删除一个OTA升级包")
+ @DeleteMapping("/deleteOtaUpgrade/{id}")
+ public R deleteOtaUpgrade(@ApiParam(value = "OTA升级包ID", required = true) @PathVariable("id") Long id) {
+ // 记录信息
+ log.info("删除OTA升级包 id: {}", id);
+ // 返回删除操作的成功响应
+ return R.ok(otaUpgradesService.deleteOtaUpgrade(id));
+ }
+
+ @ApiOperation(value = "批量删除OTA升级包", httpMethod = "DELETE", notes = "通过它们的ID批量删除OTA升级包")
+ @DeleteMapping("/deleteOtaUpgrades")
+ public R deleteOtaUpgrades(@ApiParam(value = "OTA升级包ID", required = true) @RequestBody List ids) {
+ // 记录信息
+ log.info("批量删除OTA升级包 ids: {}", ids);
+ // 检查是否所有ID对应的OTA升级包都已被删除
+ boolean allDeleted = ids.stream().distinct().allMatch(id -> otaUpgradesService.deleteOtaUpgrade(id));
+ // 返回批量删除操作的成功响应
+ return R.ok(allDeleted);
+ }
+
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradeRecordsMapper.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradeRecordsMapper.java
new file mode 100644
index 00000000..2321129b
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradeRecordsMapper.java
@@ -0,0 +1,24 @@
+package com.mqttsnet.thinglinks.link.mapper.ota;
+
+import com.mqttsnet.thinglinks.link.api.domain.ota.entity.OtaUpgradeRecords;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface OtaUpgradeRecordsMapper {
+ // 插入一条OTA升级记录
+ int insertOtaUpgradeRecords(OtaUpgradeRecords otaUpgradeRecords);
+
+ // 根据ID删除一条OTA升级记录
+ int deleteOtaUpgradeRecordsById(Long id);
+
+ // 更新一条OTA升级记录
+ int updateOtaUpgradeRecordsById(OtaUpgradeRecords otaUpgradeRecords);
+
+ // 根据ID查询一条OTA升级记录
+ OtaUpgradeRecords selectOtaUpgradeRecordsById(Long id);
+
+ // 查询所有OTA升级记录
+ List selectAllOtaUpgradeRecords();
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradeTasksMapper.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradeTasksMapper.java
new file mode 100644
index 00000000..77d5d144
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradeTasksMapper.java
@@ -0,0 +1,31 @@
+package com.mqttsnet.thinglinks.link.mapper.ota;
+
+import com.mqttsnet.thinglinks.link.api.domain.ota.entity.OtaUpgradeTasks;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface OtaUpgradeTasksMapper {
+ // 插入一条记录
+ int insertOtaUpgradeTask(OtaUpgradeTasks otaUpgradeTasks);
+
+ // 根据ID删除一条记录
+ int deleteOtaUpgradeTaskById(Long id);
+
+ // 更新一条记录
+ int updateOtaUpgradeTaskById(OtaUpgradeTasks otaUpgradeTasks);
+
+ // 根据ID查询一条记录
+ OtaUpgradeTasks selectOtaUpgradeTaskById(Long id);
+
+ // 查询所有记录
+ List selectAllOtaUpgradeTasks();
+
+ // 根据OtaUpgradeId查询
+ int getOtaUpgradeTasksByOtaUpgradeId(Long id);
+
+ //更新状态
+ int updateOtaUpgradeTasksByStatus(@Param("id") Long id, @Param("status") Integer status);
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradesMapper.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradesMapper.java
new file mode 100644
index 00000000..a97e7ebd
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/mapper/ota/OtaUpgradesMapper.java
@@ -0,0 +1,29 @@
+package com.mqttsnet.thinglinks.link.mapper.ota;
+
+
+import com.mqttsnet.thinglinks.link.api.domain.ota.entity.OtaUpgrades;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface OtaUpgradesMapper {
+
+ // 插入一条记录
+ int insertOtaUpgrades(OtaUpgrades otaUpgrades);
+ // 根据ID删除一条记录
+ int deleteOtaUpgradeById(Long id);
+
+ // 更新一条记录
+ int updateOtaUpgradeById(OtaUpgrades otaUpgrades);
+
+ // 根据ID查询一条记录
+ OtaUpgrades selectOtaUpgradeById(Long id);
+
+ // 查询所有记录
+ List selectAllOtaUpgrades();
+
+ // 根据ID修改状态
+ int updateOtaUpgradeByStatus(@Param("id") Long id, @Param("status") Integer status);
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradeRecordsService.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradeRecordsService.java
new file mode 100644
index 00000000..f38b3667
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradeRecordsService.java
@@ -0,0 +1,40 @@
+package com.mqttsnet.thinglinks.link.service.ota;
+
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradeRecordsSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradeRecordsUpdateVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.OtaCommandResponseParam;
+
+public interface OtaUpgradeRecordsService {
+
+ /**
+ * 保存新的OTA升级记录。
+ *
+ * @param saveVO 要保存的记录
+ * @return 已保存的记录
+ */
+ OtaUpgradeRecordsSaveVO saveOtaUpgradeRecord(OtaUpgradeRecordsSaveVO saveVO);
+
+ /**
+ * 更新现有的OTA升级记录。
+ *
+ * @param updateVO 要更新的记录
+ * @return 更新后的记录
+ */
+ OtaUpgradeRecordsUpdateVO updateOtaUpgradeRecord(OtaUpgradeRecordsUpdateVO updateVO);
+
+ /**
+ * 从MQTT事件中保存OTA升级记录。
+ *
+ * @param otaCommandResponseParam 包含OTA命令响应的消息主体。
+ * @return {@link OtaCommandResponseParam} 已保存的OTA升级记录。
+ */
+ OtaCommandResponseParam saveOtaUpgradeRecordByMqtt(OtaCommandResponseParam otaCommandResponseParam);
+
+ /**
+ * 从HTTP事件中保存OTA升级记录。
+ *
+ * @param otaCommandResponseParam 包含OTA命令响应的消息主体。
+ * @return {@link OtaCommandResponseParam} 已保存的OTA升级记录。
+ */
+ OtaCommandResponseParam saveUpgradeRecordByHttp(OtaCommandResponseParam otaCommandResponseParam);
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradeTasksService.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradeTasksService.java
new file mode 100644
index 00000000..12ed9fe2
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradeTasksService.java
@@ -0,0 +1,61 @@
+package com.mqttsnet.thinglinks.link.service.ota;
+
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.result.OtaUpgradeTasksResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradeTasksSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradeTasksUpdateVO;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface OtaUpgradeTasksService {
+
+ /**
+ * Save OTA Upgrade Task
+ *
+ * @param saveVO 保存参数
+ * @return {@link OtaUpgradeTasksSaveVO} 返回结果
+ */
+ OtaUpgradeTasksSaveVO saveUpgradeTask(OtaUpgradeTasksSaveVO saveVO);
+
+ /**
+ * Update OTA Upgrade Task
+ *
+ * @param updateVO 更新参数
+ * @return {@link OtaUpgradeTasksUpdateVO} 返回结果
+ */
+ OtaUpgradeTasksUpdateVO updateUpgradeTask(OtaUpgradeTasksUpdateVO updateVO);
+
+ /**
+ * Update OTA Upgrade Task Status
+ *
+ * @param id 主键
+ * @param status 状态
+ * @return {@link Boolean} 返回结果
+ */
+ boolean changeTaskStatus(Long id, Integer status);
+
+ /**
+ * Delete OTA Upgrade Task
+ *
+ * @param id 主键
+ * @return {@link Boolean} 返回结果
+ */
+ boolean deleteOtaUpgradeTask(Long id);
+
+ /**
+ * Get OTA Upgrade Task Details
+ *
+ * @param id 主键
+ * @return {@link OtaUpgradeTasksResultVO} 返回结果
+ */
+ OtaUpgradeTasksResultVO getUpgradeTaskDetails(Long id);
+
+ /**
+ * Perform ota upgrade tasks based on the start time and end time, including upgrade package information.
+ *
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return {@link OtaUpgradeTasksResultVO} OTA升级任务的详细信息。
+ */
+ List otaUpgradeTasksExecute(LocalDateTime startTime, LocalDateTime endTime);
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradesService.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradesService.java
new file mode 100644
index 00000000..0f6e1843
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/OtaUpgradesService.java
@@ -0,0 +1,33 @@
+package com.mqttsnet.thinglinks.link.service.ota;
+
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradesSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradesUpdateVO;
+
+public interface OtaUpgradesService {
+ /**
+ * Save OTA Upgrade Package
+ *
+ * @param saveVO 保存参数
+ * @return {@link OtaUpgradesSaveVO} 返回结果
+ */
+ OtaUpgradesSaveVO saveUpgradePackage(OtaUpgradesSaveVO saveVO);
+
+ /**
+ * Update OTA Upgrade Package
+ *
+ * @param updateVO 更新参数
+ * @return {@link OtaUpgradesUpdateVO} 返回结果
+ */
+ OtaUpgradesUpdateVO updateUpgradePackage(OtaUpgradesUpdateVO updateVO);
+
+ /**
+ * Update OTA Upgrade Package Status
+ *
+ * @param id 主键
+ * @param status 状态
+ * @return {@link Boolean} 返回结果
+ */
+ Boolean updateOtaUpgradeStatus(Long id, Integer status);
+
+ Boolean deleteOtaUpgrade(Long id);
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradeRecordsServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradeRecordsServiceImpl.java
new file mode 100644
index 00000000..db4f4556
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradeRecordsServiceImpl.java
@@ -0,0 +1,108 @@
+package com.mqttsnet.thinglinks.link.service.ota.impl;
+
+import com.mqttsnet.thinglinks.common.core.exception.ServiceException;
+import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
+import com.mqttsnet.thinglinks.common.security.service.TokenService;
+import com.mqttsnet.thinglinks.link.api.domain.ota.entity.OtaUpgradeRecords;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradeRecordsSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradeRecordsUpdateVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.OtaCommandResponseParam;
+import com.mqttsnet.thinglinks.link.mapper.ota.OtaUpgradeRecordsMapper;
+import com.mqttsnet.thinglinks.link.service.ota.OtaUpgradeRecordsService;
+import com.mqttsnet.thinglinks.system.api.domain.SysUser;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@Service
+public class OtaUpgradeRecordsServiceImpl implements OtaUpgradeRecordsService {
+
+ @Resource
+ private OtaUpgradeRecordsMapper otaUpgradeRecordsMapper;
+
+ @Resource
+ private TokenService tokenService;
+
+ /**
+ * 保存新的OTA升级记录。
+ *
+ * @param saveVO 要保存的记录
+ * @return 已保存的记录
+ */
+ @Override
+ public OtaUpgradeRecordsSaveVO saveOtaUpgradeRecord(OtaUpgradeRecordsSaveVO saveVO) {
+
+ validateOtaUpgradeRecordsSaveVO(saveVO);
+
+ // Validate and map the saveVO
+ OtaUpgradeRecords record = buildOtaUpgradeRecordSaveVO(saveVO);
+ otaUpgradeRecordsMapper.insertOtaUpgradeRecords(record);
+ return BeanPlusUtil.toBeanIgnoreError(record, OtaUpgradeRecordsSaveVO.class);
+ }
+
+
+ /**
+ * 更新现有的OTA升级记录。
+ *
+ * @param updateVO 要更新的记录
+ * @return 更新后的记录
+ */
+ @Override
+ public OtaUpgradeRecordsUpdateVO updateOtaUpgradeRecord(OtaUpgradeRecordsUpdateVO updateVO) {
+ validateOtaUpgradeRecordsUpdateVO(updateVO);
+
+ // Validate and fetch existing record
+ OtaUpgradeRecords existingRecord = otaUpgradeRecordsMapper.selectOtaUpgradeRecordsById(updateVO.getId());
+ if (existingRecord == null) {
+ throw new ServiceException("OTA upgrade record not found");
+ }
+
+ // Update the record
+ OtaUpgradeRecords records = buildOtaUpgradeRecordSaveVO(updateVO);
+
+ otaUpgradeRecordsMapper.updateOtaUpgradeRecordsById(records);
+
+ return BeanPlusUtil.toBeanIgnoreError(records, OtaUpgradeRecordsUpdateVO.class);
+ }
+
+
+
+ /**
+ * 从MQTT事件中保存OTA升级记录。
+ *
+ * @param otaCommandResponseParam 包含OTA命令响应的消息主体。
+ * @return {@link OtaCommandResponseParam} 已保存的OTA升级记录。
+ */
+ @Override
+ public OtaCommandResponseParam saveOtaUpgradeRecordByMqtt(OtaCommandResponseParam otaCommandResponseParam) {
+ return null;
+ }
+
+ /**
+ * 从HTTP事件中保存OTA升级记录。
+ *
+ * @param otaCommandResponseParam 包含OTA命令响应的消息主体。
+ * @return {@link OtaCommandResponseParam} 已保存的OTA升级记录。
+ */
+ @Override
+ public OtaCommandResponseParam saveUpgradeRecordByHttp(OtaCommandResponseParam otaCommandResponseParam) {
+ return null;
+ }
+
+
+ private OtaUpgradeRecords buildOtaUpgradeRecordSaveVO(T vo) {
+ SysUser sysUser = tokenService.getLoginUser().getSysUser();
+ OtaUpgradeRecords otaUpgradeRecords = BeanPlusUtil.toBeanIgnoreError(vo, OtaUpgradeRecords.class);
+ otaUpgradeRecords.setCreatedBy(sysUser.getUserName());
+ otaUpgradeRecords.setUpdatedBy(sysUser.getUserName());
+ return otaUpgradeRecords;
+ }
+
+ private void validateOtaUpgradeRecordsSaveVO(OtaUpgradeRecordsSaveVO saveVO) {
+ }
+
+ private void validateOtaUpgradeRecordsUpdateVO(OtaUpgradeRecordsUpdateVO updateVO) {
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradeTasksServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradeTasksServiceImpl.java
new file mode 100644
index 00000000..adaed3c6
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradeTasksServiceImpl.java
@@ -0,0 +1,169 @@
+package com.mqttsnet.thinglinks.link.service.ota.impl;
+
+import com.mqttsnet.thinglinks.common.core.exception.ServiceException;
+import com.mqttsnet.thinglinks.common.core.utils.ArgumentAssert;
+import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
+import com.mqttsnet.thinglinks.common.security.service.TokenService;
+import com.mqttsnet.thinglinks.link.api.domain.ota.entity.OtaUpgradeTasks;
+import com.mqttsnet.thinglinks.link.api.domain.ota.entity.OtaUpgrades;
+import com.mqttsnet.thinglinks.link.api.domain.ota.enumeration.OtaPackageStatusEnum;
+import com.mqttsnet.thinglinks.link.api.domain.ota.enumeration.OtaPackageTypeEnum;
+import com.mqttsnet.thinglinks.link.api.domain.ota.enumeration.OtaUpgradeTaskStatusEnum;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.result.OtaUpgradeTasksResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.result.OtaUpgradesResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradeTasksSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradeTasksUpdateVO;
+import com.mqttsnet.thinglinks.link.mapper.ota.OtaUpgradeTasksMapper;
+import com.mqttsnet.thinglinks.link.mapper.ota.OtaUpgradesMapper;
+import com.mqttsnet.thinglinks.link.service.ota.OtaUpgradeTasksService;
+import com.mqttsnet.thinglinks.system.api.domain.SysUser;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+@Slf4j
+@Service
+public class OtaUpgradeTasksServiceImpl implements OtaUpgradeTasksService {
+
+ @Resource
+ private OtaUpgradeTasksMapper otaUpgradeTasksMapper;
+
+ @Resource
+ private OtaUpgradesMapper otaUpgradesMapper;
+
+ @Resource
+ private TokenService tokenService;
+
+ /**
+ * Save OTA Upgrade Task
+ *
+ * @param saveVO 保存参数
+ * @return {@link OtaUpgradeTasksSaveVO} 返回结果
+ */
+ @Override
+ public OtaUpgradeTasksSaveVO saveUpgradeTask(OtaUpgradeTasksSaveVO saveVO) {
+ log.info("saveUpgradeTask saveVO: {}", saveVO);
+ validateOtaUpgradeTasksSaveVO(saveVO);
+ // Map the saveVO to your OtaUpgradeTask entity
+ OtaUpgradeTasks otaUpgradeTask = buildOtaUpgradeTaskFromSaveVO(saveVO);
+
+ // Persist the OtaUpgradeTask entity using your manager or repository
+ otaUpgradeTasksMapper.insertOtaUpgradeTask(otaUpgradeTask);
+
+ // Map the saved entity back to OtaUpgradeTasksSaveVO if needed
+ return BeanPlusUtil.toBeanIgnoreError(otaUpgradeTask, OtaUpgradeTasksSaveVO.class);
+ }
+
+ /**
+ * Update OTA Upgrade Task
+ *
+ * @param updateVO 更新参数
+ * @return {@link OtaUpgradeTasksUpdateVO} 返回结果
+ */
+ @Override
+ public OtaUpgradeTasksUpdateVO updateUpgradeTask(OtaUpgradeTasksUpdateVO updateVO) {
+ log.info("Updating OTA upgrade task: {}", updateVO);
+
+ // Validate the updateVO object
+ validateOtaUpgradeTasksUpdateVO(updateVO);
+
+ // Map the saveVO to your OtaUpgrade entity
+ OtaUpgradeTasks otaUpgradeTasks = buildOtaUpgradeTaskFromSaveVO(updateVO);
+
+ // Save the updated entity
+ otaUpgradeTasksMapper.updateOtaUpgradeTaskById(otaUpgradeTasks);
+
+
+ // Map the updated entity back to OtaUpgradeTasksUpdateVO if needed
+ return BeanPlusUtil.toBeanIgnoreError(otaUpgradeTasks, OtaUpgradeTasksUpdateVO.class);
+ }
+
+ @Override
+ public boolean changeTaskStatus(Long id, Integer status) {
+ ArgumentAssert.notNull(id, "Package ID cannot be null");
+ ArgumentAssert.notNull(status, "Status cannot be null");
+
+ OtaUpgradeTasks otaUpgradeTasks = otaUpgradeTasksMapper.selectOtaUpgradeTaskById(id);
+ if (otaUpgradeTasks == null) {
+ throw new ServiceException("OTA upgrade package does not exist");
+ }
+ if (status == otaUpgradeTasks.getTaskStatus().intValue()) {
+ throw new ServiceException("The OTA upgrade package status is the same as the current status");
+ }
+ OtaUpgradeTaskStatusEnum.fromValue(status)
+ .orElseThrow(() -> new ServiceException("Invalid task status"));
+
+ return otaUpgradeTasksMapper.updateOtaUpgradeTasksByStatus(id, status) > 0;
+ }
+
+ @Override
+ public boolean deleteOtaUpgradeTask(Long id) {
+ ArgumentAssert.notNull(id, "Task ID cannot be null");
+
+ OtaUpgradeTasks task = otaUpgradeTasksMapper.selectOtaUpgradeTaskById(id);
+ if (task == null) {
+ throw new ServiceException("OTA upgrade task does not exist");
+ }
+
+ // Additional checks can be added here, like if the task is in progress or has dependencies
+
+ return otaUpgradeTasksMapper.deleteOtaUpgradeTaskById(id) > 0;
+ }
+
+ @Override
+ public OtaUpgradeTasksResultVO getUpgradeTaskDetails(Long id) {
+ ArgumentAssert.notNull(id, "Task ID cannot be null");
+
+ OtaUpgradeTasks otaUpgradeTask = otaUpgradeTasksMapper.selectOtaUpgradeTaskById(id);
+ if (otaUpgradeTask == null) {
+ throw new ServiceException("OTA upgrade task not found");
+ }
+
+ OtaUpgradeTasksResultVO resultVO = BeanPlusUtil.toBeanIgnoreError(otaUpgradeTask, OtaUpgradeTasksResultVO.class);
+
+ OtaUpgrades otaUpgrade = otaUpgradesMapper.selectOtaUpgradeById(otaUpgradeTask.getUpgradeId());
+ if (otaUpgrade == null) {
+ throw new ServiceException("Associated OTA upgrade package not found");
+ }
+
+ OtaUpgradesResultVO otaUpgradesResultVO = BeanPlusUtil.toBeanIgnoreError(otaUpgrade, OtaUpgradesResultVO.class);
+ resultVO.setOtaUpgradesResultVO(otaUpgradesResultVO);
+ return resultVO;
+ }
+
+ @Override
+ public List otaUpgradeTasksExecute(LocalDateTime startTime, LocalDateTime endTime) {
+ //TODO 此方法 待实现
+ return null;
+ }
+
+
+ private void validateOtaUpgradeTasksUpdateVO(OtaUpgradeTasksUpdateVO updateVO) {
+ Optional.ofNullable(otaUpgradeTasksMapper.selectOtaUpgradeTaskById(updateVO.getId())).orElseThrow(() -> new ServiceException("OTA upgrade task not found"));
+ //TODO 如需其他限制 在此添加
+ }
+
+
+ private void validateOtaUpgradeTasksSaveVO(OtaUpgradeTasksSaveVO saveVO) {
+ OtaUpgradeTaskStatusEnum.fromValue(saveVO.getTaskStatus())
+ .orElseThrow(() -> new ServiceException("Invalid task status"));
+
+ OtaUpgrades otaUpgrades = otaUpgradesMapper.selectOtaUpgradeById(saveVO.getUpgradeId());
+ if (otaUpgrades == null) {
+ throw new ServiceException("OTA upgrade package does not exist");
+ }
+
+ }
+
+ private OtaUpgradeTasks buildOtaUpgradeTaskFromSaveVO(T vo) {
+ SysUser sysUser = tokenService.getLoginUser().getSysUser();
+ OtaUpgradeTasks otaUpgradeTasks = BeanPlusUtil.toBeanIgnoreError(vo, OtaUpgradeTasks.class);
+ otaUpgradeTasks.setCreatedBy(sysUser.getUserName());
+ otaUpgradeTasks.setUpdatedBy(sysUser.getUserName());
+ return otaUpgradeTasks;
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradesServiceImpl.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradesServiceImpl.java
new file mode 100644
index 00000000..9dd15ac1
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/service/ota/impl/OtaUpgradesServiceImpl.java
@@ -0,0 +1,145 @@
+package com.mqttsnet.thinglinks.link.service.ota.impl;
+
+import com.mqttsnet.thinglinks.common.core.exception.ServiceException;
+import com.mqttsnet.thinglinks.common.core.utils.ArgumentAssert;
+import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
+import com.mqttsnet.thinglinks.common.security.service.TokenService;
+import com.mqttsnet.thinglinks.link.api.domain.ota.entity.OtaUpgrades;
+import com.mqttsnet.thinglinks.link.api.domain.ota.enumeration.OtaPackageStatusEnum;
+import com.mqttsnet.thinglinks.link.api.domain.ota.enumeration.OtaPackageTypeEnum;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.save.OtaUpgradesSaveVO;
+import com.mqttsnet.thinglinks.link.api.domain.ota.vo.update.OtaUpgradesUpdateVO;
+import com.mqttsnet.thinglinks.link.mapper.ota.OtaUpgradeTasksMapper;
+import com.mqttsnet.thinglinks.link.mapper.ota.OtaUpgradesMapper;
+import com.mqttsnet.thinglinks.link.service.ota.OtaUpgradesService;
+import com.mqttsnet.thinglinks.link.service.product.ProductService;
+import com.mqttsnet.thinglinks.system.api.domain.SysUser;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Optional;
+
+@Slf4j
+@Service
+public class OtaUpgradesServiceImpl implements OtaUpgradesService {
+ @Resource
+ private OtaUpgradesMapper otaUpgradesMapper;
+ @Resource
+ private TokenService tokenService;
+
+ @Resource
+ private ProductService productService;
+
+ @Resource
+ private OtaUpgradeTasksMapper otaUpgradeTasksMapper;
+
+ /**
+ * Save OTA Upgrade Package
+ *
+ * @param saveVO 保存参数
+ * @return {@link OtaUpgradesSaveVO} 返回结果
+ */
+ @Override
+ public OtaUpgradesSaveVO saveUpgradePackage(OtaUpgradesSaveVO saveVO) {
+ log.info("saveUpgradePackage saveVO: {}", saveVO);
+ // Validate the saveVO object
+ validateOtaUpgradesSaveVO(saveVO);
+
+ // Map the saveVO to your OtaUpgrade entity
+ OtaUpgrades otaUpgrade = buildOtaUpgradesFromVO(saveVO);
+
+ // Persist the OtaUpgrade entity using your manager or repository
+ otaUpgradesMapper.insertOtaUpgrades(otaUpgrade);
+
+ // Map the saved entity back to OtaUpgradesSaveVO if needed
+ return BeanPlusUtil.toBeanIgnoreError(otaUpgrade, OtaUpgradesSaveVO.class);
+
+ }
+
+ @Override
+ public OtaUpgradesUpdateVO updateUpgradePackage(OtaUpgradesUpdateVO updateVO) {
+ log.info("Updating OTA upgrade package: {}", updateVO);
+
+ // Validate the updateVO object
+ validateOtaUpgradesUpdateVO(updateVO);
+
+ // Map the saveVO to your OtaUpgrade entity
+ OtaUpgrades otaUpgrade = buildOtaUpgradesFromVO(updateVO);
+
+ // Save the updated entity
+ otaUpgradesMapper.updateOtaUpgradeById(otaUpgrade);
+
+ // Map the updated entity back to OtaUpgradesUpdateVO if needed
+ return BeanPlusUtil.toBeanIgnoreError(otaUpgrade, OtaUpgradesUpdateVO.class);
+ }
+
+ @Override
+ public Boolean updateOtaUpgradeStatus(Long id, Integer status) {
+ ArgumentAssert.notNull(id, "Package ID cannot be null");
+ ArgumentAssert.notNull(status, "Status cannot be null");
+
+ OtaUpgrades otaUpgrades = otaUpgradesMapper.selectOtaUpgradeById(id);
+ if (otaUpgrades == null) {
+ throw new ServiceException("OTA upgrade package does not exist");
+ }
+ if (status == otaUpgrades.getStatus().intValue()) {
+ throw new ServiceException("The OTA upgrade package status is the same as the current status");
+ }
+ return otaUpgradesMapper.updateOtaUpgradeByStatus(id, status) > 0;
+
+ }
+
+ /**
+ * Deletes an OTA upgrade package by its ID if it is not in use.
+ *
+ * @param id the ID of the OTA upgrade package to delete
+ * @return {@code true} if the package was successfully deleted, {@code false} otherwise
+ * @throws IllegalArgumentException if the {@code id} is null
+ * @throws ServiceException if the OTA upgrade package does not exist or is in use
+ */
+ @Override
+ public Boolean deleteOtaUpgrade(Long id) {
+ ArgumentAssert.notNull(id, "Package ID cannot be null");
+
+ OtaUpgrades otaUpgrade = otaUpgradesMapper.selectOtaUpgradeById(id);
+ if (otaUpgrade == null) {
+ throw new ServiceException("OTA upgrade package does not exist");
+ }
+
+ int taskCount = otaUpgradeTasksMapper.getOtaUpgradeTasksByOtaUpgradeId(id);
+ if (taskCount > 0) {
+ throw new ServiceException("OTA upgrade package is in use and cannot be deleted");
+ }
+
+ boolean deleted = otaUpgradesMapper.deleteOtaUpgradeById(id) > 0;
+ if (!deleted) {
+ throw new ServiceException("Failed to delete OTA upgrade package");
+ }
+
+ return true;
+ }
+
+
+
+ private void validateOtaUpgradesUpdateVO(OtaUpgradesUpdateVO updateVO) {
+ Optional.ofNullable(otaUpgradesMapper.selectOtaUpgradeById(updateVO.getId())).orElseThrow(() -> new ServiceException("OTA upgrade package not found"));
+ String productIdentification = updateVO.getProductIdentification();
+ Optional.ofNullable(productService.selectByProductIdentification(productIdentification)).orElseThrow(() -> new ServiceException("Product identification not found"));
+ OtaPackageTypeEnum.fromValue(updateVO.getPackageType()).orElseThrow(() -> new ServiceException("Invalid package type"));
+ OtaPackageStatusEnum.fromValue(updateVO.getStatus()).orElseThrow(() -> new ServiceException("Invalid status"));
+ }
+
+ private OtaUpgrades buildOtaUpgradesFromVO(T vo) {
+ SysUser sysUser = tokenService.getLoginUser().getSysUser();
+ OtaUpgrades otaUpgrades = BeanPlusUtil.toBeanIgnoreError(vo, OtaUpgrades.class);
+ otaUpgrades.setCreatedBy(sysUser.getUserName());
+ otaUpgrades.setUpdatedBy(sysUser.getUserName());
+ return otaUpgrades;
+ }
+
+ private void validateOtaUpgradesSaveVO(OtaUpgradesSaveVO saveVO) {
+ OtaPackageTypeEnum.fromValue(saveVO.getPackageType()).orElseThrow(() -> new ServiceException("Invalid package type"));
+ OtaPackageStatusEnum.fromValue(saveVO.getStatus()).orElseThrow(() -> new ServiceException("Invalid status"));
+ }
+}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradeRecordsMapper.xml b/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradeRecordsMapper.xml
new file mode 100644
index 00000000..44d54bb4
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradeRecordsMapper.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, task_id, device_identification, upgrade_status, progress, error_code, error_message, start_time, end_time, success_details, failure_details, log_details, remark, created_time, created_by, updated_by, updated_time
+
+
+
+ INSERT INTO ota_upgrade_records
+ (task_id, device_identification, upgrade_status, progress, error_code, error_message, start_time, end_time, success_details, failure_details, log_details, remark, created_time, created_by, updated_time, updated_by)
+ VALUES
+ (#{taskId}, #{deviceIdentification}, #{upgradeStatus}, #{progress}, #{errorCode}, #{errorMessage}, #{startTime}, #{endTime}, #{successDetails}, #{failureDetails}, #{logDetails}, #{remark}, now(), #{createdBy}, now(), #{updatedBy})
+
+
+
+ DELETE FROM ota_upgrade_records WHERE id = #{id}
+
+
+
+ UPDATE ota_upgrade_records
+ SET task_id = #{taskId},
+ device_identification = #{deviceIdentification},
+ upgrade_status = #{upgradeStatus},
+ progress = #{progress},
+ error_code = #{errorCode},
+ error_message = #{errorMessage},
+ start_time = #{startTime},
+ end_time = #{endTime},
+ success_details = #{successDetails},
+ failure_details = #{failureDetails},
+ log_details = #{logDetails},
+ remark = #{remark},
+ updated_by = #{updatedBy},
+ updated_time = now()
+ WHERE id = #{id}
+
+
+
+ SELECT
+ FROM ota_upgrade_records WHERE id = #{id}
+
+
+
+ SELECT
+ FROM ota_upgrade_records
+
+
+
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradeTasksMapper.xml b/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradeTasksMapper.xml
new file mode 100644
index 00000000..5ffea372
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradeTasksMapper.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, upgrade_id, task_name, task_status, scheduled_time, description, remark, created_by, created_time, updated_by, updated_time
+
+
+
+ INSERT INTO ota_upgrade_tasks (upgrade_id, task_name, task_status, scheduled_time, description, remark, created_by, created_time, updated_by, updated_time)
+ VALUES (#{upgradeId}, #{taskName}, #{taskStatus}, #{scheduledTime}, #{description}, #{remark}, #{createdBy}, now(), #{updatedBy}, now())
+
+
+
+ DELETE FROM ota_upgrade_tasks WHERE id = #{id}
+
+
+
+ UPDATE ota_upgrade_tasks
+ SET upgrade_id = #{upgradeId},
+ task_name = #{taskName},
+ task_status = #{taskStatus},
+ scheduled_time = #{scheduledTime},
+ description = #{description},
+ remark = #{remark},
+ updated_by = #{updatedBy},
+ updated_time = now()
+ WHERE id = #{id}
+
+
+
+ SELECT
+ FROM ota_upgrade_tasks WHERE id = #{id}
+
+
+
+ SELECT
+ FROM ota_upgrade_tasks
+
+
+
+ select count(*)
+ from ota_upgrade_tasks
+ where upgrade_id = #{id}
+
+
+
+ UPDATE ota_upgrade_tasks
+ set task_status = #{status}
+ WHERE id = #{id}
+
+
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradesMapper.xml b/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradesMapper.xml
new file mode 100644
index 00000000..e4c85c93
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/resources/mapper/link/ota/OtaUpgradesMapper.xml
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, app_id, package_name, package_type, product_identification, version, file_location, status, description, custom_info, remark, created_by, created_time, updated_by, updated_time
+
+
+
+ INSERT INTO ota_upgrades
+
+
+ app_id,
+
+
+ package_name,
+
+
+ package_type,
+
+
+ product_identification,
+
+
+ version,
+
+
+ file_location,
+
+
+ status,
+
+
+ description,
+
+
+ custom_info,
+
+
+ remark,
+
+
+ created_by,
+
+ created_time,
+
+ updated_by,
+
+ updated_time,
+
+
+
+ #{appId,jdbcType=VARCHAR},
+
+
+ #{packageName,jdbcType=VARCHAR},
+
+
+ #{packageType,jdbcType=SMALLINT},
+
+
+ #{productIdentification,jdbcType=VARCHAR},
+
+
+ #{version,jdbcType=VARCHAR},
+
+
+ #{fileLocation,jdbcType=VARCHAR},
+
+
+ #{status,jdbcType=SMALLINT},
+
+
+ #{description,jdbcType=VARCHAR},
+
+
+ #{customInfo,jdbcType=LONGVARCHAR},
+
+
+ #{remark,jdbcType=VARCHAR},
+
+
+ #{createdBy,jdbcType=VARCHAR},
+
+ now(),
+
+ #{updatedBy,jdbcType=VARCHAR},
+
+ now(),
+
+
+
+
+
+ DELETE
+ FROM ota_upgrades
+ WHERE id = #{id}
+
+
+
+
+ UPDATE ota_upgrades
+ SET app_id = #{appId},
+ package_name = #{packageName},
+ package_type = #{packageType},
+ product_identification = #{productIdentification},
+ version = #{version},
+ file_location = #{fileLocation},
+ status = #{status},
+ description = #{description},
+ custom_info = #{customInfo},
+ remark = #{remark},
+ updated_by = #{updatedBy},
+ updated_time = now()
+ WHERE id = #{id}
+
+
+
+
+ SELECT
+
+ FROM ota_upgrades WHERE id = #{id}
+
+
+
+
+ SELECT
+
+ FROM ota_upgrades
+
+
+
+ UPDATE ota_upgrades
+ set status = #{status}
+ WHERE id = #{id}
+
+
From 8339d1b7d2ed3958b0baad6ee458a2136190ae66 Mon Sep 17 00:00:00 2001
From: xiaonan <13733918655@163.com>
Date: Sat, 23 Mar 2024 15:53:14 +0800
Subject: [PATCH 10/35] =?UTF-8?q?=E5=8D=87=E7=BA=A7mqtt=E8=A7=A3=E6=9E=90?=
=?UTF-8?q?=E5=8D=8F=E8=AE=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 1 +
README.zh_CN.md | 1 +
doc/sql/changeRecord/1.2.0.RELEASE.sql | 20 +-
doc/sql/thinglinks.sql | 19 +-
pom.xml | 1 +
.../link/api/RemoteDeviceInfoService.java | 17 +-
.../link/api/RemoteDeviceOpenAnyService.java | 168 +++++++
.../link/api/RemoteDeviceService.java | 138 -----
.../cache/product/ProductModelCacheVO.java | 51 +-
.../enumeration/DeviceActionStatusEnum.java | 60 +++
.../MqttProtocolTopoStatusEnum.java | 43 ++
.../product/entity/ProductProperties.java | 15 +-
.../product/entity/ProductServices.java | 30 +-
.../product/enumeration/ProductTypeEnum.java | 71 +++
.../vo/param/ProductCommandParamVO.java | 78 +++
.../param/ProductCommandRequestParamVO.java | 128 +++++
.../param/ProductCommandResponseParamVO.java | 127 +++++
.../vo/param/ProductPropertyParamVO.java | 134 +++++
.../vo/param/ProductServiceParamVO.java | 89 ++++
.../result/ProductCommandRequestResultVO.java | 115 +++++
.../ProductCommandResponseResultVO.java | 115 +++++
.../vo/result/ProductCommandResultVO.java | 76 +++
.../vo/result/ProductPropertyResultVO.java | 131 +++++
.../product/vo/result/ProductResultVO.java | 119 +++++
.../vo/result/ProductServiceResultVO.java | 90 ++++
.../result/ProtocolDataMessageResultVO.java | 2 +-
.../vo/result/TopoAddDeviceResultVO.java | 2 +-
.../result/TopoDeviceOperationResultVO.java | 2 +-
.../vo/result/TopoQueryDeviceResultVO.java | 23 +-
.../factory/RemoteDeviceFallbackFactory.java | 138 -----
.../RemoteDeviceInfoFallbackFactory.java | 1 +
.../RemoteDeviceOpenAnyFallbackFactory.java | 97 ++++
.../main/resources/META-INF/spring.factories | 1 +
.../tdengine/api/RemoteTdEngineService.java | 164 +++++-
.../tdengine/api/domain/Fields.java | 57 +--
.../api/domain/SuperTableDescribeVO.java | 2 +-
.../tdengine/api/domain/model/FieldsVO.java | 58 +++
.../api/domain/model/SuperTableDTO.java | 53 ++
.../tdengine/api/domain/model/TableDTO.java | 49 ++
.../api/domain/model/TagsSelectDTO.java | 30 ++
.../RemoteTdEngineFallbackFactory.java | 88 +++-
.../common/core/constant/Constants.java | 6 +
.../common/core/enums/DataTypeEnum.java | 102 +++-
.../common/core/enums/DeviceType.java | 11 +-
.../factory/ProtocolMessageAdapter.java | 2 +-
.../thinglinks-modules-broker/pom.xml | 5 +
.../thinglinks-modules-broker/readme.md | 0
.../broker/config/KafkaConsumerConfig.java | 2 +-
.../broker/config/KafkaProviderConfig.java | 2 +-
.../broker/mqs/event/MqttCloseEvent.java | 2 +-
.../broker/mqs/event/MqttConnectEvent.java | 2 +-
.../broker/mqs/event/MqttDisconnectEvent.java | 2 +-
.../broker/mqs/event/MqttPingEvent.java | 2 +-
.../broker/mqs/event/MqttPublishEvent.java | 2 +-
.../broker/mqs/event/MqttSubscribeEvent.java | 2 +-
.../mqs/event/MqttUnsubscribeEvent.java | 2 +-
.../listener/MqttCloseEventListener.java | 2 +-
.../listener/MqttConnectEventListener.java | 2 +-
.../listener/MqttDisconnectEventListener.java | 2 +-
.../event/listener/MqttPingEventListener.java | 2 +-
.../listener/MqttPublishEventListener.java | 2 +-
.../listener/MqttSubscribeEventListener.java | 2 +-
.../MqttUnsubscribeEventListener.java | 2 +-
.../event/publisher/MqttEventPublisher.java | 2 +-
.../handler/kafka/KafkaSendResultHandler.java | 2 +-
.../MqttMessageKafkaConsumerHandler.java | 2 +-
.../kafka/MyKafkaListenerErrorHandler.java | 2 +-
.../mqs/mqtt/handler/AddSubDeviceHandler.java | 10 +-
.../mqtt/handler/CommandResponseHandler.java | 10 +-
.../mqs/mqtt/handler/DefaultHandler.java | 2 +-
.../mqtt/handler/DeleteSubDeviceHandler.java | 10 +-
.../mqs/mqtt/handler/DeviceDatasHandler.java | 53 +-
.../handler/OtaCommandResponseHandler.java | 12 +-
.../mqs/mqtt/handler/QueryDeviceHandler.java | 10 +-
.../mqs/mqtt/handler/SecretKeyHandler.java | 7 +-
.../broker/mqs/mqtt/handler/TopicHandler.java | 2 +-
.../mqtt/handler/UpdateSubDeviceHandler.java | 14 +-
.../mqtt/handler/event/MqttMessageEvent.java | 2 +-
.../factory/AbstractMessageHandler.java | 10 +-
.../handler/factory/TopicHandlerFactory.java | 2 +-
.../handler/listener/MqttMessageListener.java | 2 +-
.../mqtt/service/MqttEventActionService.java | 2 +-
.../mqtt/service/MqttEventCommandService.java | 2 +-
.../MqttEventOtaCommandResponseService.java | 6 +-
.../controller/device/DeviceController.java | 197 --------
.../device/DeviceInfoController.java | 30 +-
.../device/DeviceOpenAnyController.java | 256 ++++++++++
.../mapper/product/ProductServicesMapper.java | 2 +-
.../service/device/DeviceInfoService.java | 57 +++
.../link/service/device/DeviceService.java | 50 --
.../device/impl/DeviceInfoServiceImpl.java | 474 ++++++++++++++++--
.../device/impl/DeviceServiceImpl.java | 134 +++--
.../product/ProductServicesService.java | 2 +-
.../impl/ProductServicesServiceImpl.java | 4 +-
.../link/product/ProductServicesMapper.xml | 65 ++-
.../common/constant/TdsConstants.java | 34 ++
.../controller/TdEngineController.java | 401 +++++++++++++--
.../tdengine/mapper/TdEngineMapper.java | 127 ++++-
.../tdengine/service/TdEngineService.java | 153 +++++-
.../service/impl/TdEngineServiceImpl.java | 88 +++-
.../tdengine/{util => utils}/TaosAspect.java | 2 +-
.../thinglinks/tdengine/utils/TdsUtils.java | 219 ++++++++
.../main/resources/mapper/TdEngineMapper.xml | 221 ++++++++
.../src/views/link/product/services/index.vue | 22 +-
104 files changed, 4537 insertions(+), 927 deletions(-)
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceOpenAnyService.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/DeviceActionStatusEnum.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/MqttProtocolTopoStatusEnum.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/enumeration/ProductTypeEnum.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandParamVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandRequestParamVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandResponseParamVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductPropertyParamVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductServiceParamVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandRequestResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandResponseResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductPropertyResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductServiceResultVO.java
create mode 100644 thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceOpenAnyFallbackFactory.java
create mode 100644 thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/FieldsVO.java
create mode 100644 thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/SuperTableDTO.java
create mode 100644 thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/TableDTO.java
create mode 100644 thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/TagsSelectDTO.java
create mode 100644 thinglinks-modules/thinglinks-modules-broker/readme.md
create mode 100644 thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceOpenAnyController.java
create mode 100644 thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/common/constant/TdsConstants.java
rename thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/{util => utils}/TaosAspect.java (96%)
create mode 100644 thinglinks-modules/thinglinks-modules-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/utils/TdsUtils.java
diff --git a/README.md b/README.md
index 07079b91..001005f6 100644
--- a/README.md
+++ b/README.md
@@ -122,6 +122,7 @@ Thanks these wonderful people, welcome to join us:
llJam 💻
qianmenfei 💻
+ wangfan1997 💻
diff --git a/README.zh_CN.md b/README.zh_CN.md
index 00ad4a28..1a010a04 100644
--- a/README.zh_CN.md
+++ b/README.zh_CN.md
@@ -118,6 +118,7 @@ Thanks these wonderful people, welcome to join us:
llJam 💻
qianmenfei 💻
+ wangfan1997 💻
diff --git a/doc/sql/changeRecord/1.2.0.RELEASE.sql b/doc/sql/changeRecord/1.2.0.RELEASE.sql
index 79f0ebd2..a4015f34 100644
--- a/doc/sql/changeRecord/1.2.0.RELEASE.sql
+++ b/doc/sql/changeRecord/1.2.0.RELEASE.sql
@@ -1,11 +1,17 @@
# 设备表新增字段
-ALTER TABLE thinglinks_test.device ADD encrypt_key varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '加密密钥';
-ALTER TABLE thinglinks_test.device ADD encrypt_vector varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '加密向量';
-ALTER TABLE thinglinks_test.device ADD sign_key varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '签名密钥';
-ALTER TABLE thinglinks_test.device ADD encrypt_method tinyint(4) DEFAULT 0 NOT NULL COMMENT '协议加密方式';
-ALTER TABLE thinglinks_test.device ADD sw_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '软件版本';
-ALTER TABLE thinglinks_test.device ADD fw_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '固件版本';
-ALTER TABLE thinglinks_test.device ADD device_sdk_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'v1' NOT NULL COMMENT 'sdk版本';
+ALTER TABLE device ADD encrypt_key varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '加密密钥';
+ALTER TABLE device ADD encrypt_vector varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '加密向量';
+ALTER TABLE device ADD sign_key varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '签名密钥';
+ALTER TABLE device ADD encrypt_method tinyint(4) DEFAULT 0 NOT NULL COMMENT '协议加密方式';
+ALTER TABLE device ADD sw_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '软件版本';
+ALTER TABLE device ADD fw_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NULL COMMENT '固件版本';
+ALTER TABLE device ADD device_sdk_version varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'v1' NOT NULL COMMENT 'sdk版本';
+
+
+#产品服务表
+ALTER TABLE product_services MODIFY COLUMN service_name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '服务名称';
+ALTER TABLE product_services ADD service_code varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' NOT NULL COMMENT '服务编码:支持英文大小写、数字、下划线和中划线';
+
diff --git a/doc/sql/thinglinks.sql b/doc/sql/thinglinks.sql
index 6d838fee..c5b69824 100644
--- a/doc/sql/thinglinks.sql
+++ b/doc/sql/thinglinks.sql
@@ -1856,15 +1856,16 @@ DROP TABLE IF EXISTS `product_services`;
CREATE TABLE `product_services`
(
`id` bigint(19) NOT NULL AUTO_INCREMENT COMMENT '服务id',
- `service_name` varchar(255) NOT NULL COMMENT '服务名称:支持英文大小写、数字、下划线和中划线\r\n',
- `template_identification` varchar(100) DEFAULT NULL COMMENT '产品模版标识',
- `product_identification` varchar(100) DEFAULT NULL COMMENT '产品标识',
- `status` varchar(10) NOT NULL DEFAULT '0' COMMENT '状态(字典值:0启用 1停用)',
- `description` varchar(255) DEFAULT NULL COMMENT '服务的描述信息:文本描述,不影响实际功能,可配置为空字符串""。\r\n',
- `create_by` varchar(64) DEFAULT 'ununited' COMMENT '创建者',
- `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
- `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `service_code` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '服务编码:支持英文大小写、数字、下划线和中划线',
+ `service_name` varchar(255) NOT NULL COMMENT '服务名称',
+ `template_identification` varchar(100) DEFAULT NULL COMMENT '产品模版标识',
+ `product_identification` varchar(100) DEFAULT NULL COMMENT '产品标识',
+ `status` varchar(10) NOT NULL DEFAULT '0' COMMENT '状态(字典值:0启用 1停用)',
+ `description` varchar(255) DEFAULT NULL COMMENT '服务的描述信息:文本描述,不影响实际功能,可配置为空字符串""。\r\n',
+ `create_by` varchar(64) DEFAULT 'ununited' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
AUTO_INCREMENT = 72
diff --git a/pom.xml b/pom.xml
index 30767838..3d0d8d62 100644
--- a/pom.xml
+++ b/pom.xml
@@ -276,6 +276,7 @@
thinglinks-api
thinglinks-common
thinglinks-registry
+ thinglinks-common/thinglinks-common-tds
pom
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceInfoService.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceInfoService.java
index 1ef01ffa..df51ea8f 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceInfoService.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceInfoService.java
@@ -1,11 +1,18 @@
package com.mqttsnet.thinglinks.link.api;
import com.mqttsnet.thinglinks.common.core.constant.ServiceNameConstants;
+import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.web.domain.AjaxResult;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoAddSubDeviceParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoDeleteSubDeviceParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoUpdateSubDeviceStatusParam;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
import com.mqttsnet.thinglinks.link.api.factory.RemoteDeviceInfoFallbackFactory;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.*;
/**
* 子设备管理服务
@@ -17,10 +24,14 @@ public interface RemoteDeviceInfoService {
/**
* 刷新子设备数据模型
+ *
* @param ids
* @return
*/
@GetMapping("/deviceInfo/refreshDeviceInfoDataModel")
- public AjaxResult refreshDeviceInfoDataModel(@RequestParam(name = "ids",required = false) Long[] ids);
+ public AjaxResult refreshDeviceInfoDataModel(@RequestParam(name = "ids", required = false) Long[] ids);
+
+
+
}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceOpenAnyService.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceOpenAnyService.java
new file mode 100644
index 00000000..da3fb97a
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceOpenAnyService.java
@@ -0,0 +1,168 @@
+
+package com.mqttsnet.thinglinks.link.api;
+
+import com.mqttsnet.thinglinks.common.core.constant.ServiceNameConstants;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.factory.RemoteDeviceOpenAnyFallbackFactory;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.Valid;
+import java.util.Map;
+
+/**
+ * 设备管理开放服务
+ *
+ * @author shisen
+ */
+@FeignClient(contextId = "remoteDeviceOpenService", value = ServiceNameConstants.THINGLINKS_LINK, fallbackFactory = RemoteDeviceOpenAnyFallbackFactory.class)
+public interface RemoteDeviceOpenAnyService {
+
+
+ /**
+ * 客户端身份认证
+ *
+ * @param params
+ * @return
+ */
+ @PostMapping("/deviceOpenAny/clientAuthentication")
+ public R clientAuthentication(@RequestBody Map params);
+
+ /**
+ * (MQTT)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @ApiOperation(value = "(MQTT)协议新增子设备档案", httpMethod = "POST", notes = "(MQTT)协议新增子设备档案")
+ @PostMapping("/deviceOpenAny/saveSubDeviceByMqtt")
+ R saveSubDeviceByMqtt(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam);
+
+
+ /**
+ * (HTTP)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @ApiOperation(value = "(HTTP)协议新增子设备档案", httpMethod = "POST", notes = "(HTTP)协议新增子设备档案")
+ @PostMapping("/deviceOpenAny/saveSubDeviceByHttp")
+ public R saveSubDeviceByHttp(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam);
+
+
+ /**
+ * MQTT协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(MQTT)协议修改子设备连接状态", httpMethod = "PUT", notes = "(MQTT)协议修改子设备连接状态")
+ @PutMapping("/deviceOpenAny/updateSubDeviceConnectStatusByMqtt")
+ R updateSubDeviceConnectStatusByMqtt(@RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam);
+
+
+ /**
+ * HTTP协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(HTTP)协议修改子设备连接状态", httpMethod = "PUT", notes = "(HTTP)协议修改子设备连接状态")
+ @PutMapping("/deviceOpenAny/updateSubDeviceConnectStatusByHttp")
+ R updateSubDeviceConnectStatusByHttp(@RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam);
+
+ /**
+ * MQTT协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(MQTT)协议删除子设备", httpMethod = "PUT", notes = "(MQTT)协议删除子设备")
+ @PutMapping("/deviceOpenAny/deleteSubDeviceByMqtt")
+ R deleteSubDeviceByMqtt(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam);
+
+
+ /**
+ * HTTP协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(HTTP)协议删除子设备", httpMethod = "PUT", notes = "(HTTP)协议删除子设备")
+ @PutMapping("/deviceOpenAny/deleteSubDeviceByHttp")
+ R deleteSubDeviceByHttp(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam);
+
+ /**
+ * MQTT协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @ApiOperation(value = "(MQTT)协议数据上报", httpMethod = "PUT", notes = "(MQTT)协议数据上报")
+ @PostMapping("/deviceDataReportByMqtt")
+ R deviceDataReportByMqtt(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam);
+
+ /**
+ * HTTP协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @ApiOperation(value = "(HTTP)协议数据上报", httpMethod = "PUT", notes = "(HTTP)协议数据上报")
+ @PostMapping("/deviceOpenAny/deviceDataReportByHttp")
+ R deviceDataReportByHttp(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam);
+
+ /**
+ * Queries device information using the MQTT protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @ApiOperation(value = "Query Device Information via MQTT Protocol", httpMethod = "POST", notes = "Queries device information using the MQTT protocol")
+ @PostMapping("/deviceOpenAny/queryDeviceByMqtt")
+ public R queryDeviceByMqtt(@RequestBody TopoQueryDeviceParam topoQueryDeviceParam);
+
+ /**
+ * Queries device information using the HTTP protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @ApiOperation(value = "Query Device Information via HTTP Protocol", httpMethod = "POST", notes = "Queries device information using the HTTP protocol")
+ @PostMapping("/deviceOpenAny/queryDeviceByHttp")
+ public R queryDeviceByHttp(@RequestBody TopoQueryDeviceParam topoQueryDeviceParam);
+
+
+ /**
+ * Receives and saves a new OTA upgrade record from an MQTT message. This endpoint
+ * captures the command response parameters from the MQTT message body and persists them.
+ *
+ * @param otaCommandResponseParam The response parameters from an OTA command sent via MQTT.
+ * @return {@link R} A response entity containing the saved OTA upgrade record.
+ */
+ @ApiOperation(value = "Save OTA Upgrade Record", httpMethod = "POST", notes = "Saves a new OTA upgrade record from MQTT message data.")
+ @PostMapping("/deviceOpenAny/saveUpgradeRecordByMqtt")
+ public R saveUpgradeRecordByMqtt(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam);
+
+
+ /**
+ * Receives and saves a new OTA upgrade record from an HTTP request. This endpoint
+ * captures the command response parameters from the request body and persists them.
+ *
+ * @param otaCommandResponseParam The response parameters from an OTA command sent via HTTP.
+ * @return {@link R} A response wrapper containing the saved OTA upgrade record.
+ */
+ @ApiOperation(value = "Save OTA Upgrade Record via HTTP", httpMethod = "POST", notes = "Saves a new OTA upgrade record from HTTP request data.")
+ @PostMapping("/deviceOpenAny/saveUpgradeRecordByHttp")
+ public R saveUpgradeRecordByHttp(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam);
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceService.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceService.java
index 00e2b08a..ac5fd4e7 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceService.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/RemoteDeviceService.java
@@ -3,17 +3,10 @@
import com.mqttsnet.thinglinks.common.core.constant.ServiceNameConstants;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
-import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
import com.mqttsnet.thinglinks.link.api.factory.RemoteDeviceFallbackFactory;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
-import javax.validation.Valid;
import java.util.List;
import java.util.Map;
@@ -85,135 +78,4 @@ public R selectByProductIdentificationAndDeviceIdentification(@PathVaria
@PostMapping("/device/selectDeviceByDeviceIdentificationList")
public R> selectDeviceByDeviceIdentificationList(@RequestBody List deviceIdentificationList);
- /**
- * (MQTT)协议新增子设备档案
- *
- * @param topoAddSubDeviceParam 子设备参数
- * @return {@link TopoAddDeviceResultVO} 新增结果
- */
- @ApiOperation(value = "(MQTT)协议新增子设备档案", httpMethod = "POST", notes = "(MQTT)协议新增子设备档案")
- @PostMapping("/saveSubDeviceByMqtt")
- R saveSubDeviceByMqtt(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam);
-
-
- /**
- * (HTTP)协议新增子设备档案
- *
- * @param topoAddSubDeviceParam 子设备参数
- * @return {@link TopoAddDeviceResultVO} 新增结果
- */
- @ApiOperation(value = "(HTTP)协议新增子设备档案", httpMethod = "POST", notes = "(HTTP)协议新增子设备档案")
- @PostMapping("/saveSubDeviceByHttp")
- public R saveSubDeviceByHttp(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam);
-
-
- /**
- * MQTT协议修改子设备连接状态
- *
- * @param topoUpdateSubDeviceStatusParam 连接状态参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @ApiOperation(value = "(MQTT)协议修改子设备连接状态", httpMethod = "PUT", notes = "(MQTT)协议修改子设备连接状态")
- @PutMapping("/updateSubDeviceConnectStatusByMqtt")
- R updateSubDeviceConnectStatusByMqtt(@RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam);
-
-
- /**
- * HTTP协议修改子设备连接状态
- *
- * @param topoUpdateSubDeviceStatusParam 连接状态参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @ApiOperation(value = "(HTTP)协议修改子设备连接状态", httpMethod = "PUT", notes = "(HTTP)协议修改子设备连接状态")
- @PutMapping("/updateSubDeviceConnectStatusByHttp")
- R updateSubDeviceConnectStatusByHttp(@RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam);
-
- /**
- * MQTT协议删除子设备
- *
- * @param topoDeleteSubDeviceParam 删除参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @ApiOperation(value = "(MQTT)协议删除子设备", httpMethod = "PUT", notes = "(MQTT)协议删除子设备")
- @PutMapping("/deleteSubDeviceByMqtt")
- R deleteSubDeviceByMqtt(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam);
-
-
- /**
- * HTTP协议删除子设备
- *
- * @param topoDeleteSubDeviceParam 删除参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @ApiOperation(value = "(HTTP)协议删除子设备", httpMethod = "PUT", notes = "(HTTP)协议删除子设备")
- @PutMapping("/deleteSubDeviceByHttp")
- R deleteSubDeviceByHttp(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam);
-
-
- /**
- * MQTT协议数据上报
- *
- * @param topoDeviceDataReportParam 数据上报参数
- * @return {@link TopoDeviceOperationResultVO} 上报结果
- */
- @ApiOperation(value = "(MQTT)协议数据上报", httpMethod = "PUT", notes = "(MQTT)协议数据上报")
- @PostMapping("/deviceDataReportByMqtt")
- R deviceDataReportByMqtt(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam);
-
- /**
- * HTTP协议数据上报
- *
- * @param topoDeviceDataReportParam 数据上报参数
- * @return {@link TopoDeviceOperationResultVO} 上报结果
- */
- @ApiOperation(value = "(HTTP)协议数据上报", httpMethod = "PUT", notes = "(HTTP)协议数据上报")
- @PostMapping("/deviceDataReportByHttp")
- R deviceDataReportByHttp(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam);
-
- /**
- * Queries device information using the MQTT protocol.
- *
- * @param topoQueryDeviceParam The device query parameters.
- * @return {@link TopoQueryDeviceResultVO} The result of the device query.
- */
- @ApiOperation(value = "Query Device Information via MQTT Protocol", httpMethod = "POST", notes = "Queries device information using the MQTT protocol")
- @PostMapping("/queryDeviceByMqtt")
- public R queryDeviceByMqtt(@RequestBody TopoQueryDeviceParam topoQueryDeviceParam);
-
- /**
- * Queries device information using the HTTP protocol.
- *
- * @param topoQueryDeviceParam The device query parameters.
- * @return {@link TopoQueryDeviceResultVO} The result of the device query.
- */
- @ApiOperation(value = "Query Device Information via HTTP Protocol", httpMethod = "POST", notes = "Queries device information using the HTTP protocol")
- @PostMapping("/queryDeviceByHttp")
- public R queryDeviceByHttp(@RequestBody TopoQueryDeviceParam topoQueryDeviceParam);
-
-
- /**
- * Receives and saves a new OTA upgrade record from an MQTT message. This endpoint
- * captures the command response parameters from the MQTT message body and persists them.
- *
- * @param otaCommandResponseParam The response parameters from an OTA command sent via MQTT.
- * @return {@link R} A response entity containing the saved OTA upgrade record.
- */
- @ApiOperation(value = "Save OTA Upgrade Record", httpMethod = "POST", notes = "Saves a new OTA upgrade record from MQTT message data.")
- @PostMapping("/saveUpgradeRecordByMqtt")
- public R saveUpgradeRecordByMqtt(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam);
-
-
- /**
- * Receives and saves a new OTA upgrade record from an HTTP request. This endpoint
- * captures the command response parameters from the request body and persists them.
- *
- * @param otaCommandResponseParam The response parameters from an OTA command sent via HTTP.
- * @return {@link R} A response wrapper containing the saved OTA upgrade record.
- */
- @ApiOperation(value = "Save OTA Upgrade Record via HTTP", httpMethod = "POST", notes = "Saves a new OTA upgrade record from HTTP request data.")
- @PostMapping("/saveUpgradeRecordByHttp")
- public R saveUpgradeRecordByHttp(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam);
-
-
-
}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
index 38fcd65b..40894c8f 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/cache/product/ProductModelCacheVO.java
@@ -1,12 +1,14 @@
package com.mqttsnet.thinglinks.link.api.domain.cache.product;
import cn.hutool.core.map.MapUtil;
-import com.mqttsnet.thinglinks.link.api.domain.product.model.ProductModel;
+import com.mqttsnet.thinglinks.link.api.domain.product.vo.param.ProductServiceParamVO;
import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
+import java.util.List;
import java.util.Map;
/**
@@ -26,8 +28,53 @@
@Builder
@AllArgsConstructor
@ApiModel(value = "ProductModelCacheVO", description = "产品模型缓存VO")
-public class ProductModelCacheVO extends ProductModel implements Serializable {
+public class ProductModelCacheVO implements Serializable {
private static final long serialVersionUID = 1L;
private Map echoMap = MapUtil.newHashMap();
+
+ @ApiModelProperty(value = "租户ID")
+ private Long tenantId;
+
+ @ApiModelProperty(value = "应用ID")
+ private String appId;
+
+ @ApiModelProperty(value = "产品标识")
+ private String productIdentification;
+
+ @ApiModelProperty(value = "模板ID")
+ private Long templateId;
+
+ @ApiModelProperty(value = "产品名称")
+ private String productName;
+
+ @ApiModelProperty(value = "产品类型")
+ private Integer productType;
+
+ @ApiModelProperty(value = "厂商ID")
+ private String manufacturerId;
+
+ @ApiModelProperty(value = "厂商名称")
+ private String manufacturerName;
+
+ @ApiModelProperty(value = "产品型号")
+ private String model;
+
+ @ApiModelProperty(value = "数据格式")
+ private String dataFormat;
+
+ @ApiModelProperty(value = "设备类型")
+ private String deviceType;
+
+ @ApiModelProperty(value = "协议类型")
+ private String protocolType;
+
+ @ApiModelProperty(value = "产品版本")
+ private String productVersion;
+
+ @ApiModelProperty(value = "产品描述")
+ private String remark;
+
+ @ApiModelProperty(value = "产品模型服务")
+ private List services;
}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/DeviceActionStatusEnum.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/DeviceActionStatusEnum.java
new file mode 100644
index 00000000..db5c0dd9
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/DeviceActionStatusEnum.java
@@ -0,0 +1,60 @@
+package com.mqttsnet.thinglinks.link.api.domain.device.enumeration;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ *
+ * 设备动作状态 枚举
+ *
+ *
+ * @author shihuan sun
+ * @date 2023-08-20
+ */
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+@ApiModel(value = "DeviceActionStatusEnum", description = "设备动作状态 枚举")
+public enum DeviceActionStatusEnum {
+ /**
+ * 成功
+ */
+ SUCCESSFUL("successful", "成功"),
+
+ /**
+ * 失败
+ */
+ FAIL("fall", "失败"),
+ ;
+
+ private String value;
+ private String desc;
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+
+ /**
+ * 根据key获取对应的枚举
+ *
+ * @param value 设备连接的状态值
+ * @return 返回对应的枚举,如果没找到则返回 Optional.empty()
+ */
+ public static Optional fromValue(Integer value) {
+ return Stream.of(DeviceActionStatusEnum.values())
+ .filter(status -> status.getValue().equals(value))
+ .findFirst();
+ }
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/MqttProtocolTopoStatusEnum.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/MqttProtocolTopoStatusEnum.java
new file mode 100644
index 00000000..b4568480
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/device/enumeration/MqttProtocolTopoStatusEnum.java
@@ -0,0 +1,43 @@
+package com.mqttsnet.thinglinks.link.api.domain.device.enumeration;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * @program: thinglinks
+ * @description: MQTT协议Topo 状态枚举
+ * @packagename: com.mqttsnet.thinglinks.link.api.domain.device.enumeration
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2023-05-20 17:51
+ **/
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+@ApiModel(value = "MqttProtocolTopoStatusEnum", description = "MQTT协议Topo 状态枚举")
+public enum MqttProtocolTopoStatusEnum {
+ /**
+ * 成功
+ */
+ SUCCESS(0, "success"),
+
+ /**
+ * 失败
+ */
+ FAILURE(1, "failure"),
+ ;
+
+ private Integer value;
+ private String desc;
+
+ public void setValue(Integer value) {
+ this.value = value;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductProperties.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductProperties.java
index f079648a..dcdda37a 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductProperties.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductProperties.java
@@ -10,7 +10,7 @@
import lombok.experimental.Accessors;
/**
-
+ 产品模型服务属性表
* @Description: java类作用描述
* @Author: ShiHuan Sun
* @E-mail: 13733918655@163.com
@@ -20,11 +20,7 @@
* @UpdateDate: 2021/12/25$ 23:52$
* @UpdateRemark: 修改内容
* @Version: 1.0
-
*/
-/**
- * 产品模型服务属性表
- */
@ApiModel(value="产品模型服务属性表")
@Data
@NoArgsConstructor
@@ -114,11 +110,10 @@ public class ProductProperties extends BaseEntity implements Serializable {
/**
* 指示单位。支持长度不超过50。
-取值根据参数确定,如:
-•温度单位:“C”或“K”
-•百分比单位:“%”
-•压强单位:“Pa”或“kPa”
-
+ 取值根据参数确定,如:
+ •温度单位:“C”或“K”
+ •百分比单位:“%”
+ •压强单位:“Pa”或“kPa”
*/
@ApiModelProperty(value="指示单位。支持长度不超过50。,取值根据参数确定,如:,•温度单位:“C”或“K”,•百分比单位:“%”,•压强单位:“Pa”或“kPa”,")
private String unit;
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductServices.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductServices.java
index 7002fbb5..a70f2325 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductServices.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/entity/ProductServices.java
@@ -2,20 +2,20 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
-import java.time.LocalDateTime;
-
import lombok.*;
import lombok.experimental.Accessors;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
/**
-* @program: thinglinks
-* @description: ${description}
-* @packagename: com.mqttsnet.thinglinks.link.api.domain.product.entity
-* @author: ShiHuan Sun
-* @e-mainl: 13733918655@163.com
-* @date: 2022-11-18 20:38
-**/
+ * @program: thinglinks
+ * @description: ${description}
+ * @packagename: com.mqttsnet.thinglinks.link.api.domain.product.entity
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2022-11-18 20:38
+ **/
/**
* 产品模型服务表
@@ -35,9 +35,15 @@ public class ProductServices implements Serializable {
private Long id;
/**
- * 服务名称:支持英文大小写、数字、下划线和中划线
+ * 服务编码:支持英文大小写、数字、下划线和中划线
+ */
+ @ApiModelProperty(value = "服务编码:支持英文大小写、数字、下划线和中划线")
+ private String serviceCode;
+
+ /**
+ * 服务名称
*/
- @ApiModelProperty(value = "服务名称:支持英文大小写、数字、下划线和中划线,")
+ @ApiModelProperty(value = "服务名称")
private String serviceName;
/**
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/enumeration/ProductTypeEnum.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/enumeration/ProductTypeEnum.java
new file mode 100644
index 00000000..cb5d2728
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/enumeration/ProductTypeEnum.java
@@ -0,0 +1,71 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.enumeration;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ *
+ * 产品类型
+ *
+ *
+ * @author shihuan sun
+ * @date 2023-04-14
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@ApiModel(value = "ProductTypeEnum", description = "产品类型")
+public enum ProductTypeEnum {
+
+ /**
+ * 普通产品,需直连设备
+ */
+ COMMON("COMMON", "COMMON"),
+
+ /**
+ * 网关产品,可挂载子设备
+ */
+ GATEWAY("GATEWAY", "GATEWAY"),
+
+ /**
+ * 未知产品
+ */
+ UNKNOWN("UNKNOWN", "UNKNOWN"),
+
+ ;
+
+ private String value;
+ private String desc;
+
+ /**
+ * 可选值
+ */
+ public static final List TYPE_COLLECTION = Arrays.asList(COMMON.value, GATEWAY.value, UNKNOWN.value);
+
+ public static ProductTypeEnum valueOf(Integer value) {
+ return Arrays.stream(values())
+ .filter(type -> type.getValue().equals(Optional.ofNullable(value).orElse(-1))) // 使用一个不存在的默认值,如-1
+ .findFirst()
+ .orElse(UNKNOWN); // 或者您可以选择返回一个默认的枚举值,比如UNKNOWN
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandParamVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandParamVO.java
new file mode 100644
index 00000000..9d1db60b
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandParamVO.java
@@ -0,0 +1,78 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ *
+ * 表单保存方法VO
+ * 产品模型设备服务命令表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "ProductCommandParamVO", description = "产品模型设备服务命令参数VO")
+public class ProductCommandParamVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 服务ID
+ */
+ @ApiModelProperty(value = "服务ID")
+ @NotNull(message = "请填写服务ID")
+ private Long serviceId;
+ /**
+ * 指示命令的编码,如门磁的LOCK命令、摄像头的VIDEO_RECORD命令,命令名与参数共同构成一个完整的命令。支持英文大小写、数字及下划线,长度[2,50]。
+ */
+ @ApiModelProperty(value = "指示命令的编码,如门磁的LOCK命令、摄像头的VIDEO_RECORD命令,命令名与参数共同构成一个完整的命令。支持英文大小写、数字及下划线,长度[2,50]。")
+ @NotEmpty(message = "请填写指示命令的编码,如门磁的LOCK命令、摄像头的VIDEO_RECORD命令,命令名与参数共同构成一个完整的命令。支持英文大小写、数字及下划线,长度[2,50]。")
+ @Size(max = 255, message = "指示命令的编码,如门磁的LOCK命令、摄像头的VIDEO_RECORD命令,命令名与参数共同构成一个完整的命令。支持英文大小写、数字及下划线,长度[2,50]。长度不能超过{max}")
+ private String commandCode;
+ /**
+ * 指示命令名称
+ */
+ @ApiModelProperty(value = "指示命令名称")
+ @Size(max = 255, message = "指示命令名称长度不能超过{max}")
+ private String commandName;
+ /**
+ * 命令描述。
+ */
+ @ApiModelProperty(value = "命令描述")
+ @Size(max = 255, message = "命令描述。长度不能超过{max}")
+ private String description;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ @Size(max = 500, message = "备注长度不能超过{max}")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+ @ApiModelProperty(value = "产品请求服务命令属性")
+ private List requests;
+
+ @ApiModelProperty(value = "产品响应服务命令属性")
+ private List responses;
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandRequestParamVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandRequestParamVO.java
new file mode 100644
index 00000000..d62152d9
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandRequestParamVO.java
@@ -0,0 +1,128 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ *
+ * 表单保存方法VO
+ * 产品模型设备下发服务命令属性表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "ProductCommandRequestParamVO", description = "产品模型设备下发服务命令属性表")
+public class ProductCommandRequestParamVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 服务ID
+ */
+ @ApiModelProperty(value = "服务ID")
+ @NotNull(message = "请填写服务ID")
+ private Long serviceId;
+ /**
+ * 命令ID
+ */
+ @ApiModelProperty(value = "命令ID")
+ @NotNull(message = "请填写命令ID")
+ private Long commandId;
+ /**
+ * 参数编码
+ */
+ @ApiModelProperty(value = "参数编码")
+ @Size(max = 255, message = "参数编码长度不能超过{max}")
+ private String parameterCode;
+ /**
+ * 命令中参数的名字。
+ */
+ @ApiModelProperty(value = "命令中参数的名字。")
+ @Size(max = 255, message = "命令中参数的名字。长度不能超过{max}")
+ private String parameterName;
+ /**
+ * 命令中参数的描述,不影响实际功能,可配置为空字符串。
+ */
+ @ApiModelProperty(value = "命令中参数的描述,不影响实际功能,可配置为空字符串。")
+ @Size(max = 255, message = "命令中参数的描述,不影响实际功能,可配置为空字符串。长度不能超过{max}")
+ private String parameterDescription;
+ /**
+ * 指示数据类型。取值范围:string、int、decimal
+ */
+ @ApiModelProperty(value = "指示数据类型。取值范围:string、int、decimal")
+ @NotEmpty(message = "请填写指示数据类型。取值范围:string、int、decimal")
+ @Size(max = 255, message = "指示数据类型。取值范围:string、int、decimal长度不能超过{max}")
+ private String datatype;
+ /**
+ * 指示枚举值。如开关状态status可有如下取值enumList" : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。
+ */
+ @ApiModelProperty(value = "指示枚举值。如开关状态status可有如下取值enumList : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。")
+ @Size(max = 255, message = "指示枚举值。如开关状态status可有如下取值enumList : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。长度不能超过{max}")
+ private String enumlist;
+ /**
+ * 指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。
+ */
+ @ApiModelProperty(value = "指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。")
+ @Size(max = 255, message = "指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。长度不能超过{max}")
+ private String max;
+ /**
+ * 指示字符串长度。仅当dataType为string时生效。
+ */
+ @ApiModelProperty(value = "指示字符串长度。仅当dataType为string时生效。")
+ @Size(max = 255, message = "指示字符串长度。仅当dataType为string时生效。长度不能超过{max}")
+ private String maxlength;
+ /**
+ * 指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。
+ */
+ @ApiModelProperty(value = "指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。")
+ @Size(max = 255, message = "指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。长度不能超过{max}")
+ private String min;
+ /**
+ * 指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。
+ */
+ @ApiModelProperty(value = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。")
+ @NotEmpty(message = "请填写指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。")
+ @Size(max = 255, message = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。长度不能超过{max}")
+ private String required;
+ /**
+ * 指示步长。
+ */
+ @ApiModelProperty(value = "指示步长。")
+ @Size(max = 255, message = "指示步长。长度不能超过{max}")
+ private String step;
+ /**
+ * 指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”
+ */
+ @ApiModelProperty(value = "指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”")
+ @Size(max = 255, message = "指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”长度不能超过{max}")
+ private String unit;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ @Size(max = 500, message = "备注长度不能超过{max}")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandResponseParamVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandResponseParamVO.java
new file mode 100644
index 00000000..ab807ea3
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductCommandResponseParamVO.java
@@ -0,0 +1,127 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ *
+ * 表单保存方法VO
+ * 产品模型设备响应服务命令属性表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "ProductCommandResponseParamVO", description = "产品模型设备响应服务命令属性表")
+public class ProductCommandResponseParamVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 命令ID
+ */
+ @ApiModelProperty(value = "命令ID")
+ @NotNull(message = "请填写命令ID")
+ private Long commandId;
+ /**
+ * 服务ID
+ */
+ @ApiModelProperty(value = "服务ID")
+ private Long serviceId;
+ /**
+ * 指示数据类型。取值范围:string、int、decimal
+ */
+ @ApiModelProperty(value = "指示数据类型。取值范围:string、int、decimal")
+ @NotEmpty(message = "请填写指示数据类型。取值范围:string、int、decimal")
+ @Size(max = 255, message = "指示数据类型。取值范围:string、int、decimal长度不能超过{max}")
+ private String datatype;
+ /**
+ * 指示枚举值。如开关状态status可有如下取值enumList : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。
+ */
+ @ApiModelProperty(value = "指示枚举值。如开关状态status可有如下取值enumList : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。")
+ @Size(max = 255, message = "指示枚举值。如开关状态status可有如下取值enumList : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。长度不能超过{max}")
+ private String enumlist;
+ /**
+ * 指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。
+ */
+ @ApiModelProperty(value = "指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。")
+ @Size(max = 255, message = "指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。长度不能超过{max}")
+ private String max;
+ /**
+ * 指示字符串长度。仅当dataType为string时生效。
+ */
+ @ApiModelProperty(value = "指示字符串长度。仅当dataType为string时生效。")
+ @Size(max = 255, message = "指示字符串长度。仅当dataType为string时生效。长度不能超过{max}")
+ private String maxlength;
+ /**
+ * 指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。
+ */
+ @ApiModelProperty(value = "指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。")
+ @Size(max = 255, message = "指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。长度不能超过{max}")
+ private String min;
+ /**
+ * 命令中参数的描述,不影响实际功能,可配置为空字符串。
+ */
+ @ApiModelProperty(value = "命令中参数的描述,不影响实际功能,可配置为空字符串。")
+ @Size(max = 255, message = "命令中参数的描述,不影响实际功能,可配置为空字符串。长度不能超过{max}")
+ private String parameterDescription;
+ /**
+ * 参数编码
+ */
+ @ApiModelProperty(value = "参数编码")
+ private String parameterCode;
+
+ /**
+ * 命令中参数的名字。
+ */
+ @ApiModelProperty(value = "命令中参数的名字。")
+ @Size(max = 255, message = "命令中参数的名字。长度不能超过{max}")
+ private String parameterName;
+ /**
+ * 指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。
+ */
+ @ApiModelProperty(value = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。")
+ @NotEmpty(message = "请填写指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。")
+ @Size(max = 255, message = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。长度不能超过{max}")
+ private String required;
+ /**
+ * 指示步长。
+ */
+ @ApiModelProperty(value = "指示步长。")
+ @Size(max = 255, message = "指示步长。长度不能超过{max}")
+ private String step;
+ /**
+ * 指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”
+ */
+ @ApiModelProperty(value = "指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”")
+ @Size(max = 255, message = "指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”长度不能超过{max}")
+ private String unit;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ @Size(max = 500, message = "备注长度不能超过{max}")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductPropertyParamVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductPropertyParamVO.java
new file mode 100644
index 00000000..65b73052
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductPropertyParamVO.java
@@ -0,0 +1,134 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ *
+ * 表单保存方法VO
+ * 产品模型服务属性表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "ProductPropertyParamVO", description = "产品模型服务属性参数VO")
+public class ProductPropertyParamVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 服务ID
+ */
+ @ApiModelProperty(value = "服务ID")
+ @NotNull(message = "请填写服务ID")
+ private Long serviceId;
+ /**
+ * 指示属性编码
+ */
+ @ApiModelProperty(value = "指示属性编码")
+ @NotEmpty(message = "请填写指示属性编码")
+ @Size(max = 255, message = "指示属性编码长度不能超过{max}")
+ private String propertyCode;
+ /**
+ * 指示属性名称
+ */
+ @ApiModelProperty(value = "指示属性名称")
+ @Size(max = 255, message = "指示属性名称长度不能超过{max}")
+ private String propertyName;
+ /**
+ * 指示数据类型:取值范围:string、int、decimal(float和double都可以使用此类型)、DateTime、jsonObject上报数据时,复杂类型数据格式如下:•DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z•jsonObject:自定义json结构体,平台不理解只透传
+ */
+ @ApiModelProperty(value = "指示数据类型:取值范围:string、int、decimal(float和double都可以使用此类型)、DateTime、jsonObject上报数据时,复杂类型数据格式如下:•DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z•jsonObject:自定义json结构体,平台不理解只透传")
+ @NotEmpty(message = "请填写指示数据类型:取值范围:string、int、decimal(float和double都可以使用此类型)、DateTime、jsonObject上报数据时,复杂类型数据格式如下:•DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z•jsonObject:自定义json结构体,平台不理解只透传")
+ @Size(max = 255, message = "指示数据类型:取值范围:string、int、decimal(float和double都可以使用此类型)、DateTime、jsonObject上报数据时,复杂类型数据格式如下:•DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z•jsonObject:自定义json结构体,平台不理解只透传长度不能超过{max}")
+ private String datatype;
+ /**
+ * 属性描述,不影响实际功能,可配置为空字符串。
+ */
+ @ApiModelProperty(value = "属性描述,不影响实际功能,可配置为空字符串。")
+ @Size(max = 255, message = "属性描述,不影响实际功能,可配置为空字符串。长度不能超过{max}")
+ private String description;
+ /**
+ * 指示枚举值:如开关状态status可有如下取值enumList: [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。
+ */
+ @ApiModelProperty(value = "指示枚举值:如开关状态status可有如下取值enumList: [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。")
+ @Size(max = 255, message = "指示枚举值:如开关状态status可有如下取值enumList: [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。长度不能超过{max}")
+ private String enumlist;
+ /**
+ * 指示最大值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑小于等于。
+ */
+ @ApiModelProperty(value = "指示最大值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑小于等于。")
+ @Size(max = 255, message = "指示最大值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑小于等于。长度不能超过{max}")
+ private String max;
+ /**
+ * 指示字符串长度。仅当dataType为string、DateTime时生效。
+ */
+ @ApiModelProperty(value = "指示字符串长度。仅当dataType为string、DateTime时生效。")
+ @Size(max = 255, message = "指示字符串长度。仅当dataType为string、DateTime时生效。长度不能超过{max}")
+ private String maxlength;
+ /**
+ * 指示访问模式。R:可读;W:可写;E属性值更改时上报数据取值范围:R、RW、RE、RWE
+ */
+ @ApiModelProperty(value = "指示访问模式。R:可读;W:可写;E属性值更改时上报数据取值范围:R、RW、RE、RWE")
+ @Size(max = 255, message = "指示访问模式。R:可读;W:可写;E属性值更改时上报数据取值范围:R、RW、RE、RWE长度不能超过{max}")
+ private String method;
+ /**
+ * 指示最小值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑大于等于。
+ */
+ @ApiModelProperty(value = "指示最小值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑大于等于。")
+ @Size(max = 255, message = "指示最小值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑大于等于。长度不能超过{max}")
+ private String min;
+ /**
+ * 指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。(字典值link_product_isRequired:0非必填 1必填)
+ */
+ @ApiModelProperty(value = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。(字典值link_product_isRequired:0非必填 1必填)")
+ @NotEmpty(message = "请填写指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。(字典值link_product_isRequired:0非必填 1必填)")
+ @Size(max = 255, message = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。(字典值link_product_isRequired:0非必填 1必填)长度不能超过{max}")
+ private String required;
+ /**
+ * 指示步长。
+ */
+ @ApiModelProperty(value = "指示步长。")
+ @Size(max = 255, message = "指示步长。长度不能超过{max}")
+ private String step;
+ /**
+ * 指示单位。支持长度不超过50。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”
+ */
+ @ApiModelProperty(value = "指示单位。支持长度不超过50。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”")
+ @Size(max = 255, message = "指示单位。支持长度不超过50。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”长度不能超过{max}")
+ private String unit;
+ /**
+ * 图标png图
+ */
+ @ApiModelProperty(value = "图标png图")
+ @Size(max = 255, message = "图标png图长度不能超过{max}")
+ private String icon;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ @Size(max = 500, message = "备注长度不能超过{max}")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductServiceParamVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductServiceParamVO.java
new file mode 100644
index 00000000..e511e2ed
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/param/ProductServiceParamVO.java
@@ -0,0 +1,89 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ *
+ * 表单保存方法VO
+ * 产品模型服务表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode
+@Builder
+@ApiModel(value = "ProductServiceParamVO", description = "产品模型服务参数VO")
+public class ProductServiceParamVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 产品ID
+ */
+ @ApiModelProperty(value = "产品ID")
+ private Long productId;
+ /**
+ * 服务编码:支持英文大小写、数字、下划线和中划线
+ */
+ @ApiModelProperty(value = "服务编码:支持英文大小写、数字、下划线和中划线")
+ @NotEmpty(message = "请填写服务编码:支持英文大小写、数字、下划线和中划线")
+ @Size(max = 255, message = "服务编码:支持英文大小写、数字、下划线和中划线长度不能超过{max}")
+ private String serviceCode;
+ /**
+ * 服务名称
+ */
+ @ApiModelProperty(value = "服务名称")
+ @Size(max = 255, message = "服务名称长度不能超过{max}")
+ private String serviceName;
+ /**
+ * 服务类型
+ */
+ @ApiModelProperty(value = "服务类型")
+ @Size(max = 255, message = "服务类型长度不能超过{max}")
+ private String serviceType;
+ /**
+ * 状态(字典值:0启用 1停用)
+ */
+ @ApiModelProperty(value = "状态(字典值:0启用 1停用)")
+ @NotNull(message = "请填写状态(字典值:0启用 1停用)")
+ private Integer serviceStatus;
+ /**
+ * 服务的描述信息:文本描述,不影响实际功能,可配置为空字符串。
+ */
+ @ApiModelProperty(value = "服务的描述信息:文本描述,不影响实际功能,可配置为空字符串。")
+ @Size(max = 255, message = "服务的描述信息:文本描述,不影响实际功能,可配置为空字符串。长度不能超过{max}")
+ private String description;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ @Size(max = 500, message = "备注长度不能超过{max}")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+ @ApiModelProperty(value = "产品服务命令")
+ private List commands;
+
+ @ApiModelProperty(value = "产品服务属性")
+ private List properties;
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandRequestResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandRequestResultVO.java
new file mode 100644
index 00000000..c3d89930
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandRequestResultVO.java
@@ -0,0 +1,115 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.result;
+
+import cn.hutool.core.map.MapUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ *
+ * 表单查询方法返回值VO
+ * 产品模型设备下发服务命令属性表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "ProductCommandRequestResultVO", description = "产品模型设备下发服务命令属性表")
+public class ProductCommandRequestResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+ @ApiModelProperty(value = "id")
+ private Long id;
+
+ /**
+ * 服务ID
+ */
+ @ApiModelProperty(value = "服务ID")
+ private Long serviceId;
+ /**
+ * 命令ID
+ */
+ @ApiModelProperty(value = "命令ID")
+ private Long commandId;
+ /**
+ * 参数编码
+ */
+ @ApiModelProperty(value = "参数编码")
+ private String parameterCode;
+ /**
+ * 命令中参数的名字。
+ */
+ @ApiModelProperty(value = "命令中参数的名字。")
+ private String parameterName;
+ /**
+ * 命令中参数的描述,不影响实际功能,可配置为空字符串。
+ */
+ @ApiModelProperty(value = "命令中参数的描述,不影响实际功能,可配置为空字符串。")
+ private String parameterDescription;
+ /**
+ * 指示数据类型。取值范围:string、int、decimal
+ */
+ @ApiModelProperty(value = "指示数据类型。取值范围:string、int、decimal")
+ private String datatype;
+ /**
+ * 指示枚举值。如开关状态status可有如下取值enumList" : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。
+ */
+ @ApiModelProperty(value = "指示枚举值。如开关状态status可有如下取值enumList : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。")
+ private String enumlist;
+ /**
+ * 指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。
+ */
+ @ApiModelProperty(value = "指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。")
+ private String max;
+ /**
+ * 指示字符串长度。仅当dataType为string时生效。
+ */
+ @ApiModelProperty(value = "指示字符串长度。仅当dataType为string时生效。")
+ private String maxlength;
+ /**
+ * 指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。
+ */
+ @ApiModelProperty(value = "指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。")
+ private String min;
+ /**
+ * 指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。
+ */
+ @ApiModelProperty(value = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。")
+ private String required;
+ /**
+ * 指示步长。
+ */
+ @ApiModelProperty(value = "指示步长。")
+ private String step;
+ /**
+ * 指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”
+ */
+ @ApiModelProperty(value = "指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”")
+ private String unit;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandResponseResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandResponseResultVO.java
new file mode 100644
index 00000000..402d33b9
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandResponseResultVO.java
@@ -0,0 +1,115 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.result;
+
+import cn.hutool.core.map.MapUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ *
+ * 表单查询方法返回值VO
+ * 产品模型设备响应服务命令属性表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "ProductCommandResponseResultVO", description = "产品模型设备响应服务命令属性表")
+public class ProductCommandResponseResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+ @ApiModelProperty(value = "id")
+ private Long id;
+
+ /**
+ * 命令ID
+ */
+ @ApiModelProperty(value = "命令ID")
+ private Long commandId;
+ /**
+ * 服务ID
+ */
+ @ApiModelProperty(value = "服务ID")
+ private Long serviceId;
+ /**
+ * 指示数据类型。取值范围:string、int、decimal
+ */
+ @ApiModelProperty(value = "指示数据类型。取值范围:string、int、decimal")
+ private String datatype;
+ /**
+ * 指示枚举值。如开关状态status可有如下取值enumList : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。
+ */
+ @ApiModelProperty(value = "指示枚举值。如开关状态status可有如下取值enumList : [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。")
+ private String enumlist;
+ /**
+ * 指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。
+ */
+ @ApiModelProperty(value = "指示最大值。仅当dataType为int、decimal时生效,逻辑小于等于。")
+ private String max;
+ /**
+ * 指示字符串长度。仅当dataType为string时生效。
+ */
+ @ApiModelProperty(value = "指示字符串长度。仅当dataType为string时生效。")
+ private String maxlength;
+ /**
+ * 指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。
+ */
+ @ApiModelProperty(value = "指示最小值。仅当dataType为int、decimal时生效,逻辑大于等于。")
+ private String min;
+ /**
+ * 命令中参数的描述,不影响实际功能,可配置为空字符串。
+ */
+ @ApiModelProperty(value = "命令中参数的描述,不影响实际功能,可配置为空字符串。")
+ private String parameterDescription;
+ /**
+ * 参数编码
+ */
+ @ApiModelProperty(value = "参数编码")
+ private String parameterCode;
+ /**
+ * 命令中参数的名字。
+ */
+ @ApiModelProperty(value = "命令中参数的名字。")
+ private String parameterName;
+ /**
+ * 指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。
+ */
+ @ApiModelProperty(value = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。")
+ private String required;
+ /**
+ * 指示步长。
+ */
+ @ApiModelProperty(value = "指示步长。")
+ private String step;
+ /**
+ * 指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”
+ */
+ @ApiModelProperty(value = "指示单位。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”")
+ private String unit;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandResultVO.java
new file mode 100644
index 00000000..71f86cd2
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductCommandResultVO.java
@@ -0,0 +1,76 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.result;
+
+import cn.hutool.core.map.MapUtil;;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * 表单查询方法返回值VO
+ * 产品模型设备服务命令表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "ProductCommandResultVO", description = "产品模型设备服务命令表")
+public class ProductCommandResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+ @ApiModelProperty(value = "命令id")
+ private Long id;
+
+ /**
+ * 服务ID
+ */
+ @ApiModelProperty(value = "服务ID")
+ private Long serviceId;
+ /**
+ * 指示命令的编码,如门磁的LOCK命令、摄像头的VIDEO_RECORD命令,命令名与参数共同构成一个完整的命令。支持英文大小写、数字及下划线,长度[2,50]。
+ */
+ @ApiModelProperty(value = "指示命令的编码,如门磁的LOCK命令、摄像头的VIDEO_RECORD命令,命令名与参数共同构成一个完整的命令。支持英文大小写、数字及下划线,长度[2,50]。")
+ private String commandCode;
+ /**
+ * 指示命令名称
+ */
+ @ApiModelProperty(value = "指示命令名称")
+ private String commandName;
+ /**
+ * 命令描述。
+ */
+ @ApiModelProperty(value = "命令描述。")
+ private String description;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+ @ApiModelProperty(value = "产品请求服务命令属性")
+ private List requests;
+
+ @ApiModelProperty(value = "产品响应服务命令属性")
+ private List responses;
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductPropertyResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductPropertyResultVO.java
new file mode 100644
index 00000000..9df32229
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductPropertyResultVO.java
@@ -0,0 +1,131 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.result;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.map.MapUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * 表单查询方法返回值VO
+ * 产品模型服务属性表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "ProductPropertyResultVO", description = "产品模型服务属性表")
+public class ProductPropertyResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+ private List> echoList = ListUtil.toList();
+
+ @ApiModelProperty(value = "属性id")
+ private Long id;
+
+ /**
+ * 服务ID
+ */
+ @ApiModelProperty(value = "服务ID")
+ private Long serviceId;
+ /**
+ * 指示属性编码
+ */
+ @ApiModelProperty(value = "指示属性编码")
+ private String propertyCode;
+
+ /**
+ * 指示属性值
+ */
+ @ApiModelProperty(value = "指示属性值")
+ private Object propertyValue;
+
+ /**
+ * 指示属性名称
+ */
+ @ApiModelProperty(value = "指示属性名称")
+ private String propertyName;
+ /**
+ * 指示数据类型:取值范围:string、int、decimal(float和double都可以使用此类型)、DateTime、jsonObject上报数据时,复杂类型数据格式如下:•DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z•jsonObject:自定义json结构体,平台不理解只透传
+ */
+ @ApiModelProperty(value = "指示数据类型:取值范围:string、int、decimal(float和double都可以使用此类型)、DateTime、jsonObject上报数据时,复杂类型数据格式如下:•DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z•jsonObject:自定义json结构体,平台不理解只透传")
+ private String datatype;
+ /**
+ * 属性描述,不影响实际功能,可配置为空字符串。
+ */
+ @ApiModelProperty(value = "属性描述,不影响实际功能,可配置为空字符串。")
+ private String description;
+ /**
+ * 指示枚举值:如开关状态status可有如下取值enumList: [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。
+ */
+ @ApiModelProperty(value = "指示枚举值:如开关状态status可有如下取值enumList: [OPEN,CLOSE]目前本字段是非功能性字段,仅起到描述作用。建议准确定义。")
+ private String enumlist;
+ /**
+ * 指示最大值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑小于等于。
+ */
+ @ApiModelProperty(value = "指示最大值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑小于等于。")
+ private String max;
+ /**
+ * 指示字符串长度。仅当dataType为string、DateTime时生效。
+ */
+ @ApiModelProperty(value = "指示字符串长度。仅当dataType为string、DateTime时生效。")
+ private String maxlength;
+ /**
+ * 指示访问模式。R:可读;W:可写;E属性值更改时上报数据取值范围:R、RW、RE、RWE
+ */
+ @ApiModelProperty(value = "指示访问模式。R:可读;W:可写;E属性值更改时上报数据取值范围:R、RW、RE、RWE")
+ private String method;
+ /**
+ * 指示最小值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑大于等于。
+ */
+ @ApiModelProperty(value = "指示最小值。支持长度不超过50的数字。仅当dataType为int、decimal时生效,逻辑大于等于。")
+ private String min;
+ /**
+ * 指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。(字典值link_product_isRequired:0非必填 1必填)
+ */
+ @ApiModelProperty(value = "指示本条属性是否必填,取值为0或1,默认取值1(必填)。目前本字段是非功能性字段,仅起到描述作用。(字典值link_product_isRequired:0非必填 1必填)")
+ private String required;
+ /**
+ * 指示步长。
+ */
+ @ApiModelProperty(value = "指示步长。")
+ private String step;
+ /**
+ * 指示单位。支持长度不超过50。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”
+ */
+ @ApiModelProperty(value = "指示单位。支持长度不超过50。取值根据参数确定,如:•温度单位:“C”或“K”•百分比单位:“%”•压强单位:“Pa”或“kPa”")
+ private String unit;
+ /**
+ * 图标png图
+ */
+ @ApiModelProperty(value = "图标png图")
+ private String icon;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductResultVO.java
new file mode 100644
index 00000000..52c66e81
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductResultVO.java
@@ -0,0 +1,119 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.result;
+
+import cn.hutool.core.map.MapUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * 表单查询方法返回值VO
+ * 产品模型
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "ProductResultVO", description = "产品模型")
+public class ProductResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+ @ApiModelProperty(value = "id")
+ private Long id;
+
+ /**
+ * 应用ID
+ */
+ @ApiModelProperty(value = "应用ID")
+ private String appId;
+ /**
+ * 产品id
+ */
+ @ApiModelProperty(value = "产品id")
+ private Long templateId;
+ /**
+ * 产品名称:自定义,支持中文、英文大小写、数字、下划线和中划线
+ */
+ @ApiModelProperty(value = "产品名称:自定义,支持中文、英文大小写、数字、下划线和中划线")
+ private String productName;
+ /**
+ * 产品标识
+ */
+ @ApiModelProperty(value = "产品标识")
+ private String productIdentification;
+ /**
+ * 支持以下两种产品类型1•COMMON:普通产品,需直连设备。2•GATEWAY:网关产品,可挂载子设备。 0其他未知产品
+ */
+ @ApiModelProperty(value = "支持以下两种产品类型1•COMMON:普通产品,需直连设备。2•GATEWAY:网关产品,可挂载子设备。 0其他未知产品")
+ private Integer productType;
+ /**
+ * 厂商ID:支持英文大小写,数字,下划线和中划线
+ */
+ @ApiModelProperty(value = "厂商ID:支持英文大小写,数字,下划线和中划线")
+ private String manufacturerId;
+ /**
+ * 厂商名称 :支持中文、英文大小写、数字、下划线和中划线
+ */
+ @ApiModelProperty(value = "厂商名称 :支持中文、英文大小写、数字、下划线和中划线")
+ private String manufacturerName;
+ /**
+ * 产品型号,建议包含字母或数字来保证可扩展性。支持英文大小写、数字、下划线和中划线
+ */
+ @ApiModelProperty(value = "产品型号,建议包含字母或数字来保证可扩展性。支持英文大小写、数字、下划线和中划线")
+ private String model;
+ /**
+ * 数据格式,默认为JSON无需修改。
+ */
+ @ApiModelProperty(value = "数据格式,默认为JSON无需修改。")
+ private String dataFormat;
+ /**
+ * 设备类型:支持英文大小写、数字、下划线和中划线
+ */
+ @ApiModelProperty(value = "设备类型:支持英文大小写、数字、下划线和中划线")
+ private String deviceType;
+ /**
+ * 设备接入平台的协议类型,默认为MQTT无需修改。
+ */
+ @ApiModelProperty(value = "设备接入平台的协议类型,默认为MQTT无需修改。")
+ private String protocolType;
+ /**
+ * 状态(字典值:0启用 1停用)
+ */
+ @ApiModelProperty(value = "状态(字典值:0启用 1停用)")
+ private Integer productStatus;
+ /**
+ * 产品版本
+ */
+ @ApiModelProperty(value = "产品版本")
+ private String productVersion;
+ /**
+ * 产品描述
+ */
+ @ApiModelProperty(value = "产品描述")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+
+ @ApiModelProperty(value = "产品模型服务")
+ private List services;
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductServiceResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductServiceResultVO.java
new file mode 100644
index 00000000..f6397820
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/product/vo/result/ProductServiceResultVO.java
@@ -0,0 +1,90 @@
+package com.mqttsnet.thinglinks.link.api.domain.product.vo.result;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.map.MapUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * 表单查询方法返回值VO
+ * 产品模型服务表
+ *
+ *
+ * @author mqttsnet
+ * @date 2023-03-14 19:39:59
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Builder
+@ApiModel(value = "ProductServiceResultVO", description = "产品模型服务表")
+public class ProductServiceResultVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map echoMap = MapUtil.newHashMap();
+
+ private List> echoList = ListUtil.toList();
+
+
+ @ApiModelProperty(value = "服务id")
+ private Long id;
+
+ /**
+ * 产品ID
+ */
+ @ApiModelProperty(value = "产品ID")
+ private Long productId;
+ /**
+ * 服务编码:支持英文大小写、数字、下划线和中划线
+ */
+ @ApiModelProperty(value = "服务编码:支持英文大小写、数字、下划线和中划线")
+ private String serviceCode;
+ /**
+ * 服务名称
+ */
+ @ApiModelProperty(value = "服务名称")
+ private String serviceName;
+ /**
+ * 服务类型
+ */
+ @ApiModelProperty(value = "服务类型")
+ private String serviceType;
+ /**
+ * 状态(字典值:0启用 1停用)
+ */
+ @ApiModelProperty(value = "状态(字典值:0启用 1停用)")
+ private Integer serviceStatus;
+ /**
+ * 服务的描述信息:文本描述,不影响实际功能,可配置为空字符串。
+ */
+ @ApiModelProperty(value = "服务的描述信息:文本描述,不影响实际功能,可配置为空字符串。")
+ private String description;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+ /**
+ * 创建人组织
+ */
+ @ApiModelProperty(value = "创建人组织")
+ private Long createdOrgId;
+
+ @ApiModelProperty(value = "产品服务命令")
+ private List commands;
+
+ @ApiModelProperty(value = "产品服务属性")
+ private List properties;
+
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/ProtocolDataMessageResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/ProtocolDataMessageResultVO.java
index 5b0afee6..22aa6e63 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/ProtocolDataMessageResultVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/ProtocolDataMessageResultVO.java
@@ -8,7 +8,7 @@
import java.io.Serializable;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 协议数据内容返回VO
* @packagename: com.mqttsnet.thinglinks.device.vo.result
* @author: ShiHuan Sun
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoAddDeviceResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoAddDeviceResultVO.java
index dd7289af..4cb794c5 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoAddDeviceResultVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoAddDeviceResultVO.java
@@ -9,7 +9,7 @@
import java.util.List;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 协议添加网关子设备响应信息
* @packagename: com.mqttsnet.thinglinks.device.vo.result
* @author: ShiHuan Sun
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoDeviceOperationResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoDeviceOperationResultVO.java
index 80aa939b..da821c49 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoDeviceOperationResultVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoDeviceOperationResultVO.java
@@ -12,7 +12,7 @@
import java.util.List;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 设备操作结果数据模型
* @packagename: com.mqttsnet.thinglinks.device.vo.result
* @author: ShiHuan Sun
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoQueryDeviceResultVO.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoQueryDeviceResultVO.java
index 6adad129..263a19da 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoQueryDeviceResultVO.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/domain/vo/result/TopoQueryDeviceResultVO.java
@@ -9,7 +9,7 @@
import java.util.List;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 协议查询设备档案信息响应信息
* @packagename: com.mqttsnet.thinglinks.device.vo.result
* @author: ShiHuan Sun
@@ -126,6 +126,27 @@ public static class DeviceInfo {
*/
@ApiModelProperty(value = "设备类型:0普通设备 || 1网关设备 || 2子设备 ")
private Integer nodeType;
+
+ /**
+ * 加密密钥
+ */
+ @ApiModelProperty(value = "加密密钥")
+ private String encryptKey;
+ /**
+ * 加密向量
+ */
+ @ApiModelProperty(value = "加密向量")
+ private String encryptVector;
+ /**
+ * 签名密钥
+ */
+ @ApiModelProperty(value = "签名密钥")
+ private String signKey;
+ /**
+ * 传输协议的加密方式:0-明文传输、1-SM4、2-AES
+ */
+ @ApiModelProperty(value = "传输协议的加密方式:0-明文传输、1-SM4、2-AES ")
+ private Integer encryptMethod;
/**
* 备注
*/
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceFallbackFactory.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceFallbackFactory.java
index ead39d30..59892788 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceFallbackFactory.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceFallbackFactory.java
@@ -3,10 +3,6 @@
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
-import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -72,143 +68,9 @@ public R> selectAllByProductIdentification(String productIdentification) {
@Override
public R> selectDeviceByDeviceIdentificationList(List deviceIdentificationList) {
-
return R.fail("根据设备标识列表查询设备失败:" + throwable.getMessage());
}
- /**
- * (MQTT)协议新增子设备档案
- *
- * @param topoAddSubDeviceParam 子设备参数
- * @return {@link TopoAddDeviceResultVO} 新增结果
- */
- @Override
- public R saveSubDeviceByMqtt(TopoAddSubDeviceParam topoAddSubDeviceParam) {
- return R.fail("新增子设备失败:" + throwable.getMessage());
- }
-
- /**
- * (HTTP)协议新增子设备档案
- *
- * @param topoAddSubDeviceParam 子设备参数
- * @return {@link TopoAddDeviceResultVO} 新增结果
- */
- @Override
- public R saveSubDeviceByHttp(TopoAddSubDeviceParam topoAddSubDeviceParam) {
- return R.fail("新增子设备失败:" + throwable.getMessage());
- }
-
- /**
- * MQTT协议修改子设备连接状态
- *
- * @param topoUpdateSubDeviceStatusParam 连接状态参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @Override
- public R updateSubDeviceConnectStatusByMqtt(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
- return R.fail("修改子设备连接状态失败:" + throwable.getMessage());
- }
-
- /**
- * HTTP协议修改子设备连接状态
- *
- * @param topoUpdateSubDeviceStatusParam 连接状态参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @Override
- public R updateSubDeviceConnectStatusByHttp(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
- return R.fail("修改子设备连接状态失败:" + throwable.getMessage());
- }
-
- /**
- * MQTT协议删除子设备
- *
- * @param topoDeleteSubDeviceParam 删除参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @Override
- public R deleteSubDeviceByMqtt(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
- return R.fail("删除子设备失败:" + throwable.getMessage());
- }
-
- /**
- * HTTP协议删除子设备
- *
- * @param topoDeleteSubDeviceParam 删除参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @Override
- public R deleteSubDeviceByHttp(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
- return R.fail("删除子设备失败:" + throwable.getMessage());
- }
-
- /**
- * MQTT协议数据上报
- *
- * @param topoDeviceDataReportParam 数据上报参数
- * @return {@link TopoDeviceOperationResultVO} 上报结果
- */
- @Override
- public R deviceDataReportByMqtt(TopoDeviceDataReportParam topoDeviceDataReportParam) {
- return R.fail("数据上报失败:" + throwable.getMessage());
- }
-
- /**
- * HTTP协议数据上报
- *
- * @param topoDeviceDataReportParam 数据上报参数
- * @return {@link TopoDeviceOperationResultVO} 上报结果
- */
- @Override
- public R deviceDataReportByHttp(TopoDeviceDataReportParam topoDeviceDataReportParam) {
- return R.fail("数据上报失败:" + throwable.getMessage());
- }
-
- /**
- * Queries device information using the MQTT protocol.
- *
- * @param topoQueryDeviceParam The device query parameters.
- * @return {@link TopoQueryDeviceResultVO} The result of the device query.
- */
- @Override
- public R queryDeviceByMqtt(TopoQueryDeviceParam topoQueryDeviceParam) {
- return R.fail("查询设备失败:" + throwable.getMessage());
- }
-
- /**
- * Queries device information using the HTTP protocol.
- *
- * @param topoQueryDeviceParam The device query parameters.
- * @return {@link TopoQueryDeviceResultVO} The result of the device query.
- */
- @Override
- public R queryDeviceByHttp(TopoQueryDeviceParam topoQueryDeviceParam) {
- return R.fail("查询设备失败:" + throwable.getMessage());
- }
-
- /**
- * Receives and saves a new OTA upgrade record from an MQTT message. This endpoint
- * captures the command response parameters from the MQTT message body and persists them.
- *
- * @param otaCommandResponseParam The response parameters from an OTA command sent via MQTT.
- * @return {@link R} A response entity containing the saved OTA upgrade record.
- */
- @Override
- public R saveUpgradeRecordByMqtt(OtaCommandResponseParam otaCommandResponseParam) {
- return R.fail("保存升级记录失败:" + throwable.getMessage());
- }
-
- /**
- * Receives and saves a new OTA upgrade record from an HTTP request. This endpoint
- * captures the command response parameters from the request body and persists them.
- *
- * @param otaCommandResponseParam The response parameters from an OTA command sent via HTTP.
- * @return {@link R} A response wrapper containing the saved OTA upgrade record.
- */
- @Override
- public R saveUpgradeRecordByHttp(OtaCommandResponseParam otaCommandResponseParam) {
- return R.fail("保存升级记录失败:" + throwable.getMessage());
- }
};
}
}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceInfoFallbackFactory.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceInfoFallbackFactory.java
index 9b490049..ee6f492c 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceInfoFallbackFactory.java
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceInfoFallbackFactory.java
@@ -30,6 +30,7 @@ public RemoteDeviceInfoService create(Throwable throwable) {
public AjaxResult refreshDeviceInfoDataModel(Long[] ids) {
return AjaxResult.error("刷新子设备数据模型失败:" + throwable.getMessage());
}
+
};
}
}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceOpenAnyFallbackFactory.java b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceOpenAnyFallbackFactory.java
new file mode 100644
index 00000000..696891db
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-link/src/main/java/com/mqttsnet/thinglinks/link/api/factory/RemoteDeviceOpenAnyFallbackFactory.java
@@ -0,0 +1,97 @@
+
+package com.mqttsnet.thinglinks.link.api.factory;
+
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * 设备管理开放服务降级处理
+ *
+ * @author xiaonannet
+ */
+@Component
+public class RemoteDeviceOpenAnyFallbackFactory implements FallbackFactory {
+ private static final Logger log = LoggerFactory.getLogger(RemoteDeviceOpenAnyFallbackFactory.class);
+
+ @Override
+ public RemoteDeviceOpenAnyService create(Throwable throwable) {
+ log.error("设备管理开放服务调用失败:{}", throwable.getMessage());
+ return new RemoteDeviceOpenAnyService() {
+
+ @Override
+ public R clientAuthentication(Map params) {
+ return R.fail("客户端身份认证失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R saveSubDeviceByMqtt(TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return R.fail("(MQTT)协议新增子设备档案失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R saveSubDeviceByHttp(TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return R.fail("(HTTP)协议新增子设备档案失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R updateSubDeviceConnectStatusByMqtt(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ return R.fail("MQTT协议修改子设备连接状态失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R updateSubDeviceConnectStatusByHttp(TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ return R.fail("HTTP协议修改子设备连接状态失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R deleteSubDeviceByMqtt(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ return R.fail("MQTT协议删除子设备失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R deleteSubDeviceByHttp(TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ return R.fail("HTTP协议删除子设备失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R deviceDataReportByMqtt(TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ return R.fail("MQTT协议设备数据上报失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R deviceDataReportByHttp(TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ return R.fail("HTTP协议设备数据上报失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R queryDeviceByMqtt(TopoQueryDeviceParam topoQueryDeviceParam) {
+ return R.fail("MQTT协议查询设备失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R queryDeviceByHttp(TopoQueryDeviceParam topoQueryDeviceParam) {
+ return R.fail("HTTP协议查询设备失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R saveUpgradeRecordByMqtt(OtaCommandResponseParam otaCommandResponseParam) {
+ return R.fail("MQTT协议保存升级记录失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R saveUpgradeRecordByHttp(OtaCommandResponseParam otaCommandResponseParam) {
+ return R.fail("HTTP协议保存升级记录失败:" + throwable.getMessage());
+ }
+ };
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-link/src/main/resources/META-INF/spring.factories b/thinglinks-api/thinglinks-api-link/src/main/resources/META-INF/spring.factories
index 3ec02d70..1113b41e 100644
--- a/thinglinks-api/thinglinks-api-link/src/main/resources/META-INF/spring.factories
+++ b/thinglinks-api/thinglinks-api-link/src/main/resources/META-INF/spring.factories
@@ -1,5 +1,6 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mqttsnet.thinglinks.link.api.factory.RemoteDeviceFallbackFactory,\
+ com.mqttsnet.thinglinks.link.api.factory.RemoteDeviceOpenAnyFallbackFactory, \
com.mqttsnet.thinglinks.link.api.factory.RemoteDeviceActionFallbackFactory, \
com.mqttsnet.thinglinks.link.api.factory.RemoteDeviceDatasFallbackFactory, \
com.mqttsnet.thinglinks.link.api.factory.RemoteProtocolFallbackFactory,\
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/RemoteTdEngineService.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/RemoteTdEngineService.java
index c9fcb9c4..3f0b053e 100644
--- a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/RemoteTdEngineService.java
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/RemoteTdEngineService.java
@@ -8,19 +8,23 @@
* @Version 1.0
*/
+import cn.hutool.json.JSONObject;
import com.mqttsnet.thinglinks.common.core.constant.ServiceNameConstants;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.tdengine.api.domain.SelectDto;
-import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDto;
-import com.mqttsnet.thinglinks.tdengine.api.domain.TableDto;
-import com.mqttsnet.thinglinks.tdengine.api.domain.TagsSelectDao;
+import com.mqttsnet.thinglinks.tdengine.api.domain.*;
+import com.mqttsnet.thinglinks.tdengine.api.domain.model.SuperTableDTO;
+import com.mqttsnet.thinglinks.tdengine.api.domain.model.TableDTO;
import com.mqttsnet.thinglinks.tdengine.api.factory.RemoteTdEngineFallbackFactory;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
+import java.util.List;
import java.util.Map;
@FeignClient(contextId = "remoteTdEngineService", value = ServiceNameConstants.THINGLINKS_TDENGINE, fallbackFactory = RemoteTdEngineFallbackFactory.class)
@@ -89,6 +93,7 @@ public interface RemoteTdEngineService {
/**
* 查询最新的数据带标签
+ *
* @param tagsSelectDao
* @return
*/
@@ -101,7 +106,7 @@ public interface RemoteTdEngineService {
* @param superTableDto
* @return
*/
- @PostMapping("/addColumnInStb")
+ @PostMapping("/dataOperation/addColumnInStb")
R> addColumnForSuperTable(@RequestBody SuperTableDto superTableDto);
/**
@@ -110,6 +115,153 @@ public interface RemoteTdEngineService {
* @param superTableDto
* @return
*/
- @PostMapping("/dropColumnInStb")
+ @PostMapping("/dataOperation/dropColumnInStb")
R> dropColumnForSuperTable(@RequestBody SuperTableDto superTableDto);
+
+ /**
+ * 创建时序数据库
+ *
+ * @param dataBaseName 数据库名称
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/createDatabase")
+ public R createDatabase(@RequestParam String dataBaseName);
+
+ /**
+ * 创建超级表
+ *
+ * @param superTableName 超级表名称
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/createSuperTable")
+ public R createSuperTable(@RequestParam String superTableName);
+
+ /**
+ * 创建超级表及字段
+ *
+ * @param superTableDTO 超级表信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/createSuperTableAndColumn")
+ public R createSuperTableAndColumn(@RequestBody SuperTableDTO superTableDTO);
+
+ /**
+ * 创建超级表及字段-方式二
+ *
+ * @param object 超级表json信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/createSuperTableAndColumnTwo")
+ public R createSuperTableAndColumnTwo(@RequestBody JSONObject object);
+
+ /**
+ * 创建子表
+ *
+ * @param tableDTO 子表信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/createSubTable")
+ public R createSubTable(@RequestBody TableDTO tableDTO);
+
+ /**
+ * 创建子表-方式二
+ *
+ * @param object 子表json信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/createSubTableTwo")
+ public R createSubTableTwo(@RequestBody JSONObject object);
+
+ /**
+ * 删除超级表
+ *
+ * @param superTableName
+ * @return
+ */
+ @PostMapping("/dataOperation/dropSuperTable")
+ public R dropSuperTable(@RequestParam String superTableName);
+
+ /**
+ * 超级表新增字段
+ *
+ * @param superTableDTO 数据信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/alterSuperTableColumn")
+ public R alterSuperTableColumn(@RequestBody SuperTableDTO superTableDTO);
+
+ /**
+ * 超级表删除字段
+ *
+ * @param superTableDTO 数据信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/dropSuperTableColumn")
+ public R dropSuperTableColumn(@RequestBody SuperTableDTO superTableDTO);
+
+ /**
+ * 新增标签
+ *
+ * @param superTableDTO 数据信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/alterSuperTableTag")
+ public R alterSuperTableTag(@RequestBody SuperTableDTO superTableDTO);
+
+ /**
+ * 删除标签
+ *
+ * @param superTableDTO 数据信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/dropSuperTableTag")
+ public R dropSuperTableTag(@RequestBody SuperTableDTO superTableDTO);
+
+ /**
+ * 修改标签名称
+ *
+ * @param superTableName
+ * @param oldName
+ * @param newName
+ * @return
+ */
+ @PostMapping("/dataOperation/alterSuperTableTagRename")
+ public R alterSuperTableTagRename(@RequestParam String superTableName, @RequestParam String oldName, @RequestParam String newName);
+
+
+ /**
+ * 查询超级表、子表结构
+ *
+ * @param tableName
+ * @return
+ */
+ @GetMapping("/dataOperation/describeSuperOrSubTable")
+ public R> describeSuperOrSubTable(@RequestParam(value = "tableName") String tableName);
+
+ /**
+ * 新增数据
+ *
+ * @param tableDTO 数据信息
+ * @return 执行结果
+ */
+ @PostMapping("/dataOperation/insertTableData")
+ public R insertTableData(@RequestBody TableDTO tableDTO);
+
+
+ /**
+ * Retrieves the latest data from a regular table. It fetches the most recent record
+ * within the specified time range or the last recorded data if the time range is not specified.
+ *
+ * @param tableName The name of the table.
+ * @param startTime The start time for the query range (optional).
+ * @param endTime The end time for the query range (optional).
+ * @return {@link R>>} The query result.
+ */
+ @ApiOperation(value = "Query Data from a Regular Table Within a Time Range", notes = "Fetches data within the specified time range if both start and end times are provided; otherwise, retrieves the latest record.")
+ @GetMapping("/dataOperation/getDataInRangeOrLastRecord")
+ public R>> getDataInRangeOrLastRecord(
+ @ApiParam(value = "Name of the regular table", required = true) @RequestParam(value = "tableName") String tableName,
+ @ApiParam(value = "Start time for the query", example = "1634572800000", required = false) @RequestParam(value = "startTime", required = false) Long startTime,
+ @ApiParam(value = "End time for the query", example = "1634659200000", required = false) @RequestParam(value = "endTime", required = false) Long endTime);
+
}
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/Fields.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/Fields.java
index 96afbb38..08defdc2 100644
--- a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/Fields.java
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/Fields.java
@@ -3,6 +3,8 @@
import com.mqttsnet.thinglinks.common.core.enums.DataTypeEnum;
import lombok.Data;
+import java.io.Serializable;
+
/**
* @ClassDescription: 建表的字段实体类
* @ClassName: Fields
@@ -11,8 +13,9 @@
* @Version 1.0
*/
@Data
-public class Fields {
- private static final long serialVersionUID = 1L;
+public class Fields implements Serializable {
+
+ private static final long serialVersionUID = -1L;
/**
* 字段名称
@@ -37,37 +40,25 @@ public class Fields {
public Fields() {
}
- public Fields(String fieldName, String dataType, Integer size) {
+ public Fields(String fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ public Fields(String fieldName, DataTypeEnum dataType) {
+ this.fieldName = fieldName;
+ this.dataType = dataType;
+ }
+
+ public Fields(String fieldName, DataTypeEnum dataType, Integer size) {
+ this.fieldName = fieldName;
+ this.dataType = dataType;
+ this.size = size;
+ }
+
+ public Fields(String fieldName, Object fieldValue, DataTypeEnum dataType, Integer size) {
this.fieldName = fieldName;
- //根据规则匹配字段数据类型
- switch (dataType.toLowerCase()) {
- case ("json"):
- this.dataType = DataTypeEnum.JSON;
- this.size = size;
- break;
- case ("string"):
- this.dataType = DataTypeEnum.NCHAR;
- this.size = size;
- break;
- case ("binary"):
- this.dataType = DataTypeEnum.BINARY;
- this.size = size;
- break;
- case ("int"):
- this.dataType = DataTypeEnum.INT;
- break;
- case ("bool"):
- this.dataType = DataTypeEnum.BOOL;
- break;
- case ("decimal"):
- this.dataType = DataTypeEnum.DOUBLE;
- break;
- case ("timestamp"):
- if ("eventTime".equals(fieldName)) {
- this.fieldName = "eventTime";
- }
- this.dataType = DataTypeEnum.TIMESTAMP;
- break;
- }
+ this.fieldValue = fieldValue;
+ this.dataType = dataType;
+ this.size = size;
}
}
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/SuperTableDescribeVO.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/SuperTableDescribeVO.java
index 7a05343e..e70f6f3a 100644
--- a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/SuperTableDescribeVO.java
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/SuperTableDescribeVO.java
@@ -10,7 +10,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 超级表结构VO
* @packagename: com.mqttsnet.thinglinks.tds.vo.result
* @author: ShiHuan Sun
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/FieldsVO.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/FieldsVO.java
new file mode 100644
index 00000000..bac54aee
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/FieldsVO.java
@@ -0,0 +1,58 @@
+package com.mqttsnet.thinglinks.tdengine.api.domain.model;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.mqttsnet.thinglinks.tdengine.api.domain.Fields;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Data
+public class FieldsVO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 字段名称
+ */
+ private String fieldName;
+
+ /**
+ * 字段数据类型
+ */
+ private String dataType;
+
+ /**
+ * 字段字节大小
+ */
+ private Integer size;
+
+ public FieldsVO() {
+ }
+
+ public FieldsVO(String fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ public FieldsVO(String fieldName, String dataType) {
+ this.fieldName = fieldName;
+ this.dataType = dataType;
+ }
+
+ public FieldsVO(String fieldName, String dataType, Integer size) {
+ this.fieldName = fieldName;
+ this.dataType = dataType;
+ this.size = size;
+ }
+
+ public static List toFieldsList(List fieldsVOList) {
+ return fieldsVOList.stream()
+ .map(fieldsVO -> BeanUtil.toBeanIgnoreError(fieldsVO, Fields.class))
+ .collect(Collectors.toList());
+ }
+
+ public static Fields toFields(FieldsVO fieldsVo) {
+ return BeanUtil.toBeanIgnoreError(fieldsVo, Fields.class);
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/SuperTableDTO.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/SuperTableDTO.java
new file mode 100644
index 00000000..e610a655
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/SuperTableDTO.java
@@ -0,0 +1,53 @@
+package com.mqttsnet.thinglinks.tdengine.api.domain.model;
+
+import com.mqttsnet.thinglinks.tdengine.api.domain.Fields;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+@Data
+@Builder
+public class SuperTableDTO implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /**
+ * 超级表的表结构(业务相关) 第一个字段的数据类型必须为timestamp 字符相关数据类型必须指定大小 字段名称和字段数据类型不能为空
+ */
+ private List schemaFields;
+
+ /**
+ * 超级表的标签字段,可以作为子表在超级表里的标识 字符相关数据类型必须指定大小 字段名称和字段数据类型不能为空
+ */
+ private List tagsFields;
+
+ /**
+ * 字段信息对象,超级表添加列时使用该属性
+ */
+ private Fields fields;
+
+ /**
+ * 数据库名称
+ */
+ private String dataBaseName;
+
+ /**
+ * 超级表名称
+ */
+ private String superTableName;
+
+ public SuperTableDTO() {
+
+ }
+
+ public SuperTableDTO(List schemaFields, List tagsFields, Fields fields, String dataBaseName, String superTableName) {
+ this.schemaFields = schemaFields;
+ this.tagsFields = tagsFields;
+ this.fields = fields;
+ this.dataBaseName = dataBaseName;
+ this.superTableName = superTableName;
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/TableDTO.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/TableDTO.java
new file mode 100644
index 00000000..0f57db99
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/TableDTO.java
@@ -0,0 +1,49 @@
+package com.mqttsnet.thinglinks.tdengine.api.domain.model;
+
+import com.mqttsnet.thinglinks.tdengine.api.domain.Fields;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class TableDTO implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+ /**
+ * 超级表普通列字段的值 值需要与创建超级表时普通列字段的数据类型对应上
+ */
+ private List schemaFieldValues;
+
+ /**
+ * 超级表标签字段的值 值需要与创建超级表时标签字段的数据类型对应上
+ */
+ private List tagsFieldValues;
+
+ /**
+ * 子表名称
+ */
+ private String tableName;
+
+ /**
+ * 数据库名称
+ */
+ private String dataBaseName;
+
+ /**
+ * 超级表名称
+ */
+ private String superTableName;
+
+ public TableDTO() {
+
+ }
+
+ public TableDTO(List schemaFieldValues, List tagsFieldValues, String tableName, String dataBaseName, String superTableName) {
+ this.schemaFieldValues = schemaFieldValues;
+ this.tagsFieldValues = tagsFieldValues;
+ this.tableName = tableName;
+ this.dataBaseName = dataBaseName;
+ this.superTableName = superTableName;
+ }
+}
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/TagsSelectDTO.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/TagsSelectDTO.java
new file mode 100644
index 00000000..4fbf2944
--- /dev/null
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/domain/model/TagsSelectDTO.java
@@ -0,0 +1,30 @@
+package com.mqttsnet.thinglinks.tdengine.api.domain.model;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @program: thinglinks
+ * @description: 标签查询模型
+ * @packagename: com.mqttsnet.thinglinks.tdengine.api.domain.rule
+ * @author: ShiHuan Sun
+ * @e-mainl: 13733918655@163.com
+ * @date: 2022-07-27 18:40
+ **/
+@Data
+public class TagsSelectDTO {
+
+ private String dataBaseName;
+
+ @NotBlank(message = "invalid operation: stableName can not be empty")
+ private String stableName;
+
+ @NotBlank(message = "invalid operation: tagsName can not be empty")
+ private String tagsName;
+
+ private Long startTime;
+
+ private Long endTime;
+
+}
diff --git a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/factory/RemoteTdEngineFallbackFactory.java b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/factory/RemoteTdEngineFallbackFactory.java
index b665177d..13c7581a 100644
--- a/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/factory/RemoteTdEngineFallbackFactory.java
+++ b/thinglinks-api/thinglinks-api-tdengine/src/main/java/com/mqttsnet/thinglinks/tdengine/api/factory/RemoteTdEngineFallbackFactory.java
@@ -1,16 +1,19 @@
package com.mqttsnet.thinglinks.tdengine.api.factory;
+import cn.hutool.json.JSONObject;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.tdengine.api.RemoteTdEngineService;
-import com.mqttsnet.thinglinks.tdengine.api.domain.SelectDto;
-import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDto;
-import com.mqttsnet.thinglinks.tdengine.api.domain.TableDto;
-import com.mqttsnet.thinglinks.tdengine.api.domain.TagsSelectDao;
+import com.mqttsnet.thinglinks.tdengine.api.domain.*;
+import com.mqttsnet.thinglinks.tdengine.api.domain.model.SuperTableDTO;
+import com.mqttsnet.thinglinks.tdengine.api.domain.model.TableDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
+import java.util.List;
+import java.util.Map;
+
/**
* @ClassDescription: 时序数据库服务降级处理
* @ClassName: RemoteTdEngineFallbackFactory
@@ -89,6 +92,83 @@ public R> addColumnForSuperTable(SuperTableDto superTableDto) {
public R> dropColumnForSuperTable(SuperTableDto superTableDto) {
return R.fail("删除列字段失败:{}", throwable.getMessage());
}
+
+ @Override
+ public R createDatabase(String dataBaseName) {
+ return R.fail("创建数据库失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R createSuperTable(String superTableName) {
+ return R.fail("创建超级表失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R createSuperTableAndColumn(SuperTableDTO superTableDTO) {
+ return R.fail("创建超级表及字段失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R createSuperTableAndColumnTwo(JSONObject object) {
+ return R.fail("创建超级表及字段-方式二失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R createSubTable(TableDTO tableDTO) {
+ return R.fail("创建子表失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R createSubTableTwo(JSONObject object) {
+ return R.fail("创建子表-方式二失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R dropSuperTable(String superTableName) {
+ return R.fail("删除超级表失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R alterSuperTableColumn(SuperTableDTO superTableDTO) {
+ return R.fail("修改超级表列失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R dropSuperTableColumn(SuperTableDTO superTableDTO) {
+ return R.fail("删除超级表列失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R alterSuperTableTag(SuperTableDTO superTableDTO) {
+ return R.fail("修改超级表Tag失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R dropSuperTableTag(SuperTableDTO superTableDTO) {
+ return R.fail("删除超级表Tag失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R alterSuperTableTagRename(String superTableName, String oldName, String newName) {
+ return R.fail("修改超级表Tag名称失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R> describeSuperOrSubTable(String tableName) {
+ log.error("查询超级表、子表结构失败:{}", throwable.getMessage());
+ return R.fail();
+ }
+
+ @Override
+ public R insertTableData(TableDTO tableDTO) {
+ return R.fail("新增数据失败:{}", throwable.getMessage());
+ }
+
+ @Override
+ public R>> getDataInRangeOrLastRecord(String tableName, Long startTime, Long endTime) {
+ log.error("查询超级表、子表结构失败:{}", throwable.getMessage());
+ return R.fail();
+ }
};
}
}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/Constants.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/Constants.java
index d42c11d4..224175ee 100644
--- a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/Constants.java
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/constant/Constants.java
@@ -146,4 +146,10 @@ public class Constants {
*/
public static final String RESUBMIT_URL_KEY = "resubmit_url:";
+ /**
+ * 下划线
+ */
+ public static final String UNDERLINE = "_";
+
+
}
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DataTypeEnum.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DataTypeEnum.java
index b5929940..fbe68217 100644
--- a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DataTypeEnum.java
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DataTypeEnum.java
@@ -1,75 +1,149 @@
package com.mqttsnet.thinglinks.common.core.enums;
+import io.swagger.annotations.ApiModel;
+import lombok.Getter;
+
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* @EnumDescription: tdEngine支持的数据类型的枚举类
* @EnumName: DataTypeEnum
* @Author: thinglinks
* @Date: 2021-12-27 16:32:53
*/
+@Getter
+@ApiModel(value = "DataTypeEnum", description = "TD数据类型-枚举")
public enum DataTypeEnum {
-
/**
* 时间戳 缺省精度毫秒(格林威治时间开始)
*/
- TIMESTAMP("timestamp"),
+ TIMESTAMP("timestamp", false),
/**
* 单字节整形 范围[-127, 127] -128用作于NULL
*/
- TINYINT("tinyint"),
+ TINYINT("tinyint", false),
/**
* 短整型 范围[-32767, 32767] -32768用作于NULL
*/
- SMALLINT("smallint"),
+ SMALLINT("smallint", false),
/**
* 整形 范围[-2^31+1, 2^31-1] -2^31用作于NULL
*/
- INT("int"),
+ INT("int", false),
/**
* 长整型 范围[-2^63+1, 2^63-1] -2^63用作于NULL
*/
- BIGINT("bigint"),
+ BIGINT("bigint", false),
/**
* 浮点型 有效位数6-7 范围[-3.4E38, 3.4E38]
*/
- FLOAT("float"),
+ FLOAT("float", false),
/**
* 双精度浮点型 有效位数15-16 范围[-1.7E308, 1.7E308]
*/
- DOUBLE("double"),
+ DOUBLE("double", false),
/**
* 单字节字符串(建议只用于处理ASCII可见字符)最大长度16000
*/
- BINARY("binary"),
+ BINARY("binary", true),
/**
* 记录包含多字节字符在内的字符串(如中文字符)最大长度4093
*/
- NCHAR("nchar"),
+ NCHAR("nchar", true),
/**
* 布尔型 {true, false}
*/
- BOOL("bool"),
+ BOOL("bool", false),
/**
* json数据类型 只有tag类型可以是json格式
*/
- JSON("json");
+ JSON("json", true),
+
+ /**
+ * 可变长的二进制数据
+ */
+ VARBINARY("varBinary", true);
private final String dataType;
+ private final boolean quoted;
- DataTypeEnum(String dataType) {
+ private static final ConcurrentHashMap DATA_TYPE_MAPPING = new ConcurrentHashMap<>();
+
+ static {
+ // 标准映射关系
+ for (DataTypeEnum type : values()) {
+ DATA_TYPE_MAPPING.put(type.dataType.toLowerCase(), type);
+ }
+
+ // 特殊映射关系或别名
+ DATA_TYPE_MAPPING.put("string", NCHAR);
+ DATA_TYPE_MAPPING.put("varchar", NCHAR);
+ DATA_TYPE_MAPPING.put("decimal", DOUBLE);
+ DATA_TYPE_MAPPING.put("nvarchar", NCHAR);
+ DATA_TYPE_MAPPING.put("jsonObject", NCHAR);
+ DATA_TYPE_MAPPING.put("int", INT);
+ DATA_TYPE_MAPPING.put("bigint", BIGINT);
+ DATA_TYPE_MAPPING.put("DateTime", NCHAR);
+ DATA_TYPE_MAPPING.put("timestamp", TIMESTAMP);
+ DATA_TYPE_MAPPING.put("bool", BOOL);
+
+ // 这里添加其他映射关系。例如:
+ DATA_TYPE_MAPPING.put("text", NCHAR); // 例如:将"text"也映射到NCHAR
+ // 可以继续根据需要增加更多映射
+ }
+
+ /**
+ * 通过dataType返回对应的枚举
+ *
+ * @param dataType 数据类型字符串
+ * @return 对应的枚举,如果没有找到则返回null
+ */
+ public static DataTypeEnum valueOfByDataType(String dataType) {
+ if (dataType == null) {
+ return NCHAR; // 可替换为默认枚举值,如 UNKNOWN
+ }
+
+ return DATA_TYPE_MAPPING.computeIfAbsent(dataType.trim().toLowerCase(), key -> {
+ // 这里处理未知的dataType,默认返回null,也可以返回例如:UNKNOWN。
+ return NCHAR;
+ });
+ }
+
+
+ /**
+ * 判断类型是否一致
+ *
+ * @param otherDataType
+ * @return {@link Boolean} ture|false
+ */
+ public boolean isTypeEqual(String otherDataType) {
+ return Optional.ofNullable(otherDataType)
+ .map(String::trim)
+ .map(this.dataType::equalsIgnoreCase)
+ .orElse(false);
+ }
+
+ DataTypeEnum(String dataType, boolean quoted) {
this.dataType = dataType;
+ this.quoted = quoted;
}
public String getDataType() {
return dataType;
}
-}
+
+ public boolean isQuoted() {
+ return quoted;
+ }
+}
\ No newline at end of file
diff --git a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceType.java b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceType.java
index fd284fc2..a61b60f1 100644
--- a/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceType.java
+++ b/thinglinks-common/thinglinks-common-core/src/main/java/com/mqttsnet/thinglinks/common/core/enums/DeviceType.java
@@ -2,6 +2,7 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
+import lombok.NoArgsConstructor;
/**
* @Description: 设备类型
@@ -20,18 +21,18 @@ public enum DeviceType {
/**
* 普通设备(无子设备也无父设备)
*/
- COMMON("COMMON","COMMON"),
+ COMMON("COMMON", "COMMON"),
/**
* 网关设备(可挂载子设备)
*/
- GATEWAY("GATEWAY","GATEWAY"),
+ GATEWAY("GATEWAY", "GATEWAY"),
/**
* 子设备(归属于某个网关设备)
*/
- SUBSET("SUBSET","SUBSET");
+ SUBSET("SUBSET", "SUBSET");
- private String key;
- private String value;
+ private String key;
+ private String value;
}
diff --git a/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/factory/ProtocolMessageAdapter.java b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/factory/ProtocolMessageAdapter.java
index 1a5ab6c9..027ff84b 100644
--- a/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/factory/ProtocolMessageAdapter.java
+++ b/thinglinks-common/thinglinks-common-protocol/src/main/java/com/mqttsnet/basic/protocol/factory/ProtocolMessageAdapter.java
@@ -13,7 +13,7 @@
import org.springframework.stereotype.Component;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 协议信息适配器
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/pom.xml b/thinglinks-modules/thinglinks-modules-broker/pom.xml
index cb237e9f..27ee1299 100644
--- a/thinglinks-modules/thinglinks-modules-broker/pom.xml
+++ b/thinglinks-modules/thinglinks-modules-broker/pom.xml
@@ -98,6 +98,11 @@
thinglinks-modules-link
${thinglinks.version}
+
+ com.mqttsnet
+ thinglinks-modules-tdengine
+ ${thinglinks.version}
+
diff --git a/thinglinks-modules/thinglinks-modules-broker/readme.md b/thinglinks-modules/thinglinks-modules-broker/readme.md
new file mode 100644
index 00000000..e69de29b
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaConsumerConfig.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaConsumerConfig.java
index 14ffa5ab..0a06499a 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaConsumerConfig.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaConsumerConfig.java
@@ -17,7 +17,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: KafkaConsumerConfig
* @packagename: com.mqttsnet.thinglinks.config.kafka
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaProviderConfig.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaProviderConfig.java
index 5a2cca04..d650e249 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaProviderConfig.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/config/KafkaProviderConfig.java
@@ -14,7 +14,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: KafkaProviderConfig
* @packagename: com.mqttsnet.thinglinks.config.kafka
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttCloseEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttCloseEvent.java
index b50b4864..d303e952 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttCloseEvent.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttCloseEvent.java
@@ -4,7 +4,7 @@
import org.springframework.context.ApplicationEvent;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description:
* @packagename: com.mqttsnet.thinglinks.mqtt.event
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttConnectEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttConnectEvent.java
index 090cdd45..093d600a 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttConnectEvent.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttConnectEvent.java
@@ -4,7 +4,7 @@
import org.springframework.context.ApplicationEvent;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description:
* @packagename: com.mqttsnet.thinglinks.mqtt.event
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttDisconnectEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttDisconnectEvent.java
index 95c2aedf..d50b6283 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttDisconnectEvent.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttDisconnectEvent.java
@@ -4,7 +4,7 @@
import org.springframework.context.ApplicationEvent;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MqttDisconnectEvent
* @packagename: com.mqttsnet.thinglinks.mqtt.event
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPingEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPingEvent.java
index 9fd98460..cc31e446 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPingEvent.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPingEvent.java
@@ -4,7 +4,7 @@
import org.springframework.context.ApplicationEvent;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MqttPingEvent
* @packagename: com.mqttsnet.thinglinks.mqtt.event
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPublishEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPublishEvent.java
index d64d908f..19bdf4e1 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPublishEvent.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttPublishEvent.java
@@ -4,7 +4,7 @@
import org.springframework.context.ApplicationEvent;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MqttPublishEvent
* @packagename: com.mqttsnet.thinglinks.mqtt.event
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttSubscribeEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttSubscribeEvent.java
index 82f2293a..6b24374d 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttSubscribeEvent.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttSubscribeEvent.java
@@ -4,7 +4,7 @@
import org.springframework.context.ApplicationEvent;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MqttSubscribeEvent
* @packagename: com.mqttsnet.thinglinks.mqtt.event
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttUnsubscribeEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttUnsubscribeEvent.java
index 82987257..31051bef 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttUnsubscribeEvent.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/MqttUnsubscribeEvent.java
@@ -4,7 +4,7 @@
import org.springframework.context.ApplicationEvent;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MqttUnsubscribeEvent
* @packagename: com.mqttsnet.thinglinks.mqtt.event
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttCloseEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttCloseEventListener.java
index 057d4375..18a956a3 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttCloseEventListener.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttCloseEventListener.java
@@ -21,7 +21,7 @@
import java.util.Optional;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MQTT CLOSE事件监听器
* @packagename: com.mqttsnet.thinglinks.mqtt.listener
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttConnectEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttConnectEventListener.java
index 361047e2..4c17644b 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttConnectEventListener.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttConnectEventListener.java
@@ -21,7 +21,7 @@
import java.util.Optional;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MQTT CONNECT事件监听器
* @packagename: com.mqttsnet.thinglinks.mqtt.listener
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttDisconnectEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttDisconnectEventListener.java
index 524e0ae4..6849df7d 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttDisconnectEventListener.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttDisconnectEventListener.java
@@ -21,7 +21,7 @@
import java.util.Optional;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MQTT DISCONNECT事件监听器
* @packagename: com.mqttsnet.thinglinks.mqtt.listener
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPingEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPingEventListener.java
index d0598b4e..b79dc140 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPingEventListener.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPingEventListener.java
@@ -7,7 +7,7 @@
import org.springframework.stereotype.Component;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MQTT PING事件监听器
* @packagename: com.mqttsnet.thinglinks.mqtt.listener
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPublishEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPublishEventListener.java
index 8862421c..117a6a71 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPublishEventListener.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttPublishEventListener.java
@@ -14,7 +14,7 @@
import org.springframework.stereotype.Component;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MqttPublish事件监听器
* @packagename: com.mqttsnet.thinglinks.consumer.mqtt.listener
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttSubscribeEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttSubscribeEventListener.java
index e2ec4041..2d8e4a37 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttSubscribeEventListener.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttSubscribeEventListener.java
@@ -10,7 +10,7 @@
import org.springframework.stereotype.Component;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MQTT SUBSCRIBE事件监听器
* @packagename: com.mqttsnet.thinglinks.mqtt.listener
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttUnsubscribeEventListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttUnsubscribeEventListener.java
index c264ffdb..6c9958e9 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttUnsubscribeEventListener.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/listener/MqttUnsubscribeEventListener.java
@@ -10,7 +10,7 @@
import org.springframework.stereotype.Component;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MQTT UNSUBSCRIBE事件监听器
* @packagename: com.mqttsnet.thinglinks.mqtt.listener
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/publisher/MqttEventPublisher.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/publisher/MqttEventPublisher.java
index 07167d16..fb1dafea 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/publisher/MqttEventPublisher.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/event/publisher/MqttEventPublisher.java
@@ -8,7 +8,7 @@
import org.springframework.stereotype.Component;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MQTT事件发布器 用于发布MQTT事件 TODO MqttEventEnum 事件枚举类 用于定义MQTT事件 预留
* @packagename: com.mqttsnet.thinglinks.consumer.mqtt.publisher
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaSendResultHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaSendResultHandler.java
index b0da2eeb..ee0d2df1 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaSendResultHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/KafkaSendResultHandler.java
@@ -8,7 +8,7 @@
import org.springframework.stereotype.Component;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: kafka消息发送回调
* @packagename: com.mqttsnet.thinglinks.common.kafka.handler
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MqttMessageKafkaConsumerHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MqttMessageKafkaConsumerHandler.java
index 2e63b4fc..249ff394 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MqttMessageKafkaConsumerHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MqttMessageKafkaConsumerHandler.java
@@ -19,7 +19,7 @@
import java.util.Optional;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: Mqtt Message kafka监听消息
* @packagename: com.mqttsnet.thinglinks.kafka
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MyKafkaListenerErrorHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MyKafkaListenerErrorHandler.java
index e11696ad..efb1801f 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MyKafkaListenerErrorHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/handler/kafka/MyKafkaListenerErrorHandler.java
@@ -9,7 +9,7 @@
import org.springframework.stereotype.Component;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: kafkaListener异常处理
* @packagename: com.mqttsnet.thinglinks.common.kafka.handler
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/AddSubDeviceHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/AddSubDeviceHandler.java
index 5b8e5644..d5bd07f2 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/AddSubDeviceHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/AddSubDeviceHandler.java
@@ -8,7 +8,7 @@
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoAddSubDeviceParam;
import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
@@ -19,7 +19,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 处理ADD_SUB_DEVICE主题
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -33,10 +33,10 @@ public class AddSubDeviceHandler extends AbstractMessageHandler implements Topic
private static final ObjectMapper objectMapper = new ObjectMapper();
public AddSubDeviceHandler(CacheDataHelper cacheDataHelper,
- RemoteDeviceService remoteDeviceService,
+ RemoteDeviceOpenAnyService remoteDeviceOpenAnyService,
RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
ProtocolMessageAdapter protocolMessageAdapter) {
- super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ super(cacheDataHelper, remoteDeviceOpenAnyService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
}
/**
@@ -108,7 +108,7 @@ protected String processingTopicMessage(Object topoAddSubDeviceParam) throws Exc
}
TopoAddSubDeviceParam addParam = (TopoAddSubDeviceParam) topoAddSubDeviceParam;
- R mqttTopoAddDeviceResultVOR = remoteDeviceService.saveSubDeviceByMqtt(addParam);
+ R mqttTopoAddDeviceResultVOR = remoteDeviceOpenAnyService.saveSubDeviceByMqtt(addParam);
log.info("Processing /topo/add Topic result: {}", JSON.toJSONString(mqttTopoAddDeviceResultVOR));
return JSON.toJSONString(mqttTopoAddDeviceResultVOR.getData());
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/CommandResponseHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/CommandResponseHandler.java
index 9be09dae..56d3aead 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/CommandResponseHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/CommandResponseHandler.java
@@ -2,8 +2,10 @@
import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
import com.mqttsnet.basic.protocol.model.EncryptionDetailsDTO;
+import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventCommandService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
import lombok.extern.slf4j.Slf4j;
@@ -13,7 +15,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 处理COMMAND_RESPONSE主题
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -24,10 +26,10 @@
@Service
public class CommandResponseHandler extends AbstractMessageHandler implements TopicHandler {
public CommandResponseHandler(CacheDataHelper cacheDataHelper,
- DeviceOpenAnyTenantApi deviceOpenAnyTenantApi,
- MqttBrokerOpenAnyTenantApi mqttBrokerOpenAnyTenantApi,
+ RemoteDeviceService remoteDeviceService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
ProtocolMessageAdapter protocolMessageAdapter) {
- super(cacheDataHelper, deviceOpenAnyTenantApi, mqttBrokerOpenAnyTenantApi, protocolMessageAdapter);
+ super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
}
@Autowired
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DefaultHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DefaultHandler.java
index 5164ebca..a6f25b3b 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DefaultHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DefaultHandler.java
@@ -4,7 +4,7 @@
import org.springframework.stereotype.Service;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 其他默认Topic处理器
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeleteSubDeviceHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeleteSubDeviceHandler.java
index df94f290..64489e9a 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeleteSubDeviceHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeleteSubDeviceHandler.java
@@ -8,7 +8,7 @@
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoDeleteSubDeviceParam;
import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
@@ -19,7 +19,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 处理DELETE_SUB_DEVICE主题
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -33,10 +33,10 @@ public class DeleteSubDeviceHandler extends AbstractMessageHandler implements To
private static final ObjectMapper objectMapper = new ObjectMapper();
public DeleteSubDeviceHandler(CacheDataHelper cacheDataHelper,
- RemoteDeviceService remoteDeviceService,
+ RemoteDeviceOpenAnyService remoteDeviceOpenAnyService,
RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
ProtocolMessageAdapter protocolMessageAdapter) {
- super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ super(cacheDataHelper, remoteDeviceOpenAnyService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
}
/**
@@ -102,7 +102,7 @@ public void handle(String topic, String qos, String body) {
*/
@Override
protected String processingTopicMessage(Object topoDeleteSubDeviceParam) throws Exception {
- R mqttTopoDeleteDeviceResultVOR = remoteDeviceService.deleteSubDeviceByMqtt((TopoDeleteSubDeviceParam) topoDeleteSubDeviceParam);
+ R mqttTopoDeleteDeviceResultVOR = remoteDeviceOpenAnyService.deleteSubDeviceByMqtt((TopoDeleteSubDeviceParam) topoDeleteSubDeviceParam);
log.info("processingTopoDeleteTopic Processing result:{}", JSON.toJSONString(mqttTopoDeleteDeviceResultVOR));
return JSON.toJSONString(mqttTopoDeleteDeviceResultVOR.getData());
}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeviceDatasHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeviceDatasHandler.java
index f4739c01..a91e78a1 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeviceDatasHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/DeviceDatasHandler.java
@@ -7,21 +7,37 @@
import com.mqttsnet.basic.protocol.model.ProtocolDataMessageDTO;
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.enums.DataTypeEnum;
+import com.mqttsnet.thinglinks.common.core.enums.ResultEnum;
+import com.mqttsnet.thinglinks.common.core.utils.DateUtils;
+import com.mqttsnet.thinglinks.common.core.utils.StringUtils;
import com.mqttsnet.thinglinks.common.core.utils.bean.BeanPlusUtil;
-import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductModelCacheVO;
+import com.mqttsnet.thinglinks.link.api.domain.product.enumeration.ProductTypeEnum;
+import com.mqttsnet.thinglinks.link.api.domain.product.vo.param.ProductServiceParamVO;
+import com.mqttsnet.thinglinks.link.api.domain.product.vo.result.ProductPropertyResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.product.vo.result.ProductResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.product.vo.result.ProductServiceResultVO;
import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoDeviceDataReportParam;
import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
+import com.mqttsnet.thinglinks.tdengine.api.RemoteTdEngineService;
+import com.mqttsnet.thinglinks.tdengine.api.domain.Fields;
+import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDescribeVO;
+import com.mqttsnet.thinglinks.tdengine.api.domain.model.TableDTO;
+import com.mqttsnet.thinglinks.tdengine.common.constant.TdsConstants;
+import com.mqttsnet.thinglinks.tdengine.utils.TdsUtils;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 处理DEVICE_DATA主题
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -33,14 +49,14 @@
public class DeviceDatasHandler extends AbstractMessageHandler implements TopicHandler {
public DeviceDatasHandler(CacheDataHelper cacheDataHelper,
- RemoteDeviceService remoteDeviceService,
- RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
- ProtocolMessageAdapter protocolMessageAdapter) {
- super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ RemoteDeviceOpenAnyService remoteDeviceOpenAnyService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceOpenAnyService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
}
- @Autowired
- private TdsApi tdsApi;
+ @Resource
+ private RemoteTdEngineService remoteTdEngineService;
/**
@@ -141,7 +157,7 @@ protected String processingTopicMessage(Object deviceDataParam) throws Exception
//如果是空,需要做设备的初始化动作,并缓存模型表结构
if (CollUtil.isEmpty(productModelSuperTableCacheVO)) {
- R> superTableDescribeVOListR = tdsApi.describeSuperOrSubTable(subTableName);
+ R> superTableDescribeVOListR = remoteTdEngineService.describeSuperOrSubTable(subTableName);
List existingFields = Optional.ofNullable(superTableDescribeVOListR.getData()).orElse(Collections.emptyList());
@@ -157,12 +173,12 @@ protected String processingTopicMessage(Object deviceDataParam) throws Exception
fields.setDataType(DataTypeEnum.BINARY);
tagsFieldValues.add(fields);
tableDTO.setTagsFieldValues(tagsFieldValues);
- R subTable = tdsApi.createSubTable(tableDTO);
- if (Boolean.TRUE.equals(subTable.getIsSuccess())) {
+ R subTable = remoteTdEngineService.createSubTable(tableDTO);
+ if (ResultEnum.SUCCESS.getCode() == subTable.getCode()) {
log.info("设备初始化,设备标识:{},服务标识:{},初始化成功", deviceCacheVO.getDeviceIdentification(), service.getServiceCode());
// 查询新的表结构信息存redis
setProductModelSuperTableCacheVO(Optional.ofNullable(deviceCacheVO.getProductIdentification()).orElse(""),
- service.getServiceCode(), deviceCacheVO.getDeviceIdentification(), tdsApi.describeSuperOrSubTable(superTableName).getData());
+ service.getServiceCode(), deviceCacheVO.getDeviceIdentification(), remoteTdEngineService.describeSuperOrSubTable(superTableName).getData());
} else {
log.warn("设备初始化 ,设备标识:{},服务标识:{},初始化失败", deviceCacheVO.getDeviceIdentification(), service.getServiceCode());
@@ -235,9 +251,9 @@ protected String processingTopicMessage(Object deviceDataParam) throws Exception
tableDTO.setSchemaFieldValues(schemaFieldsStream);
tableDTO.setTagsFieldValues(tagsFieldsStream);
- R insertedResult = tdsApi.insertTableData(tableDTO);
+ R insertedResult = remoteTdEngineService.insertTableData(tableDTO);
- if (Boolean.TRUE.equals(insertedResult.getIsSuccess())) {
+ if (ResultEnum.SUCCESS.getCode() == insertedResult.getCode()) {
log.info("insert table data success, tableName:{}", subTableName);
} else {
log.error("insert table data failed, tableName:{}", subTableName);
@@ -262,8 +278,11 @@ protected String processingTopicMessage(Object deviceDataParam) throws Exception
});
log.info("productResultVO: {}", JSON.toJSONString(productResultVO));
- setDeviceDataCollectionPoolCacheVO(Optional.ofNullable(deviceCacheVO.getProductIdentification()).orElse(""),
- deviceCacheVO.getDeviceIdentification(), productResultVO);
+
+
+ // TODO 后续处理数据收集池缓存
+ /*setDeviceDataCollectionPoolCacheVO(Optional.ofNullable(deviceCacheVO.getProductIdentification()).orElse(""),
+ deviceCacheVO.getDeviceIdentification(), productResultVO);*/
});
return JSON.toJSONString("");
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/OtaCommandResponseHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/OtaCommandResponseHandler.java
index 67015df9..5c3ee2ca 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/OtaCommandResponseHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/OtaCommandResponseHandler.java
@@ -5,7 +5,7 @@
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.service.MqttEventOtaCommandResponseService;
-import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
import lombok.extern.slf4j.Slf4j;
@@ -15,7 +15,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 处理OTA_COMMAND_RESPONSE主题
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -26,10 +26,10 @@
@Service
public class OtaCommandResponseHandler extends AbstractMessageHandler implements TopicHandler {
public OtaCommandResponseHandler(CacheDataHelper cacheDataHelper,
- RemoteDeviceService remoteDeviceService,
- RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
- ProtocolMessageAdapter protocolMessageAdapter) {
- super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ RemoteDeviceOpenAnyService remoteDeviceOpenAnyService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceOpenAnyService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
}
@Autowired
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/QueryDeviceHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/QueryDeviceHandler.java
index a53f457b..5277b405 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/QueryDeviceHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/QueryDeviceHandler.java
@@ -8,7 +8,7 @@
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoQueryDeviceParam;
import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
@@ -19,7 +19,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 处理QUERY_DEVICE主题
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -33,10 +33,10 @@ public class QueryDeviceHandler extends AbstractMessageHandler implements TopicH
private static final ObjectMapper objectMapper = new ObjectMapper();
public QueryDeviceHandler(CacheDataHelper cacheDataHelper,
- RemoteDeviceService remoteDeviceService,
+ RemoteDeviceOpenAnyService remoteDeviceOpenAnyService,
RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
ProtocolMessageAdapter protocolMessageAdapter) {
- super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ super(cacheDataHelper, remoteDeviceOpenAnyService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
}
/**
@@ -106,7 +106,7 @@ protected String processingTopicMessage(Object topoQueryDeviceParam) throws Exce
}
TopoQueryDeviceParam queryParam = (TopoQueryDeviceParam) topoQueryDeviceParam;
- R topoQueryDeviceResultVOR = remoteDeviceService.queryDeviceByMqtt(queryParam);
+ R topoQueryDeviceResultVOR = remoteDeviceOpenAnyService.queryDeviceByMqtt(queryParam);
log.info("Processing /topo/query result: {}", JSON.toJSONString(topoQueryDeviceResultVOR));
return JSON.toJSONString(topoQueryDeviceResultVOR.getData());
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/SecretKeyHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/SecretKeyHandler.java
index 5408ad73..5583c4d5 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/SecretKeyHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/SecretKeyHandler.java
@@ -5,6 +5,7 @@
import com.mqttsnet.basic.protocol.factory.ProtocolMessageAdapter;
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
@@ -14,7 +15,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 处理SECRET_KEY主题
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -28,10 +29,10 @@ public class SecretKeyHandler extends AbstractMessageHandler implements TopicHan
private static final ObjectMapper objectMapper = new ObjectMapper();
public SecretKeyHandler(CacheDataHelper cacheDataHelper,
- RemoteDeviceService remoteDeviceService,
+ RemoteDeviceOpenAnyService remoteDeviceOpenAnyService,
RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
ProtocolMessageAdapter protocolMessageAdapter) {
- super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ super(cacheDataHelper, remoteDeviceOpenAnyService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
}
/**
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/TopicHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/TopicHandler.java
index 09c460f2..f25bba85 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/TopicHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/TopicHandler.java
@@ -1,7 +1,7 @@
package com.mqttsnet.thinglinks.broker.mqs.mqtt.handler;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description:
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/UpdateSubDeviceHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/UpdateSubDeviceHandler.java
index 1dd8f0be..de008715 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/UpdateSubDeviceHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/UpdateSubDeviceHandler.java
@@ -8,7 +8,7 @@
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.mqs.mqtt.handler.factory.AbstractMessageHandler;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.api.domain.vo.param.TopoUpdateSubDeviceStatusParam;
import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
@@ -19,7 +19,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 处理UPDATE_SUB_DEVICE主题
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -33,10 +33,10 @@ public class UpdateSubDeviceHandler extends AbstractMessageHandler implements To
private static final ObjectMapper objectMapper = new ObjectMapper();
public UpdateSubDeviceHandler(CacheDataHelper cacheDataHelper,
- RemoteDeviceService remoteDeviceService,
- RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
- ProtocolMessageAdapter protocolMessageAdapter) {
- super(cacheDataHelper, remoteDeviceService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
+ RemoteDeviceOpenAnyService remoteDeviceOpenAnyService,
+ RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
+ ProtocolMessageAdapter protocolMessageAdapter) {
+ super(cacheDataHelper, remoteDeviceOpenAnyService, remoteMqttBrokerOpenApi, protocolMessageAdapter);
}
/**
@@ -102,7 +102,7 @@ public void handle(String topic, String qos, String body) {
@Override
protected String processingTopicMessage(Object topoUpdateSubDeviceParam) throws Exception {
R topoDeviceOperationResultVOR =
- remoteDeviceService.updateSubDeviceConnectStatusByMqtt((TopoUpdateSubDeviceStatusParam) topoUpdateSubDeviceParam);
+ remoteDeviceOpenAnyService.updateSubDeviceConnectStatusByMqtt((TopoUpdateSubDeviceStatusParam) topoUpdateSubDeviceParam);
log.info("processingTopoUpdateTopic Processing result:{}", JSON.toJSONString(topoDeviceOperationResultVOR));
return JSON.toJSONString(topoDeviceOperationResultVOR.getData());
}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/event/MqttMessageEvent.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/event/MqttMessageEvent.java
index 77c5bba0..efe983c0 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/event/MqttMessageEvent.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/event/MqttMessageEvent.java
@@ -3,7 +3,7 @@
import org.springframework.context.ApplicationEvent;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MessageEvent
* @packagename: com.mqttsnet.thinglinks.mqtt.handle.event
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/AbstractMessageHandler.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/AbstractMessageHandler.java
index 51fab2bb..a50aad38 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/AbstractMessageHandler.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/AbstractMessageHandler.java
@@ -5,7 +5,7 @@
import com.mqttsnet.thinglinks.broker.api.RemoteMqttBrokerOpenApi;
import com.mqttsnet.thinglinks.broker.api.domain.vo.PublishMessageRequestVO;
import com.mqttsnet.thinglinks.common.core.utils.SnowflakeIdUtil;
-import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.api.domain.cache.product.ProductModelCacheVO;
import com.mqttsnet.thinglinks.link.common.cache.helper.CacheDataHelper;
@@ -15,7 +15,7 @@
import java.util.List;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: 通用逻辑处理器
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
@@ -26,16 +26,16 @@
public abstract class AbstractMessageHandler {
protected final CacheDataHelper cacheDataHelper;
- protected final RemoteDeviceService remoteDeviceService;
+ protected final RemoteDeviceOpenAnyService remoteDeviceOpenAnyService;
protected final RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi;
protected final ProtocolMessageAdapter protocolMessageAdapter;
public AbstractMessageHandler(CacheDataHelper cacheDataHelper,
- RemoteDeviceService remoteDeviceService,
+ RemoteDeviceOpenAnyService remoteDeviceOpenAnyService,
RemoteMqttBrokerOpenApi remoteMqttBrokerOpenApi,
ProtocolMessageAdapter protocolMessageAdapter) {
this.cacheDataHelper = cacheDataHelper;
- this.remoteDeviceService = remoteDeviceService;
+ this.remoteDeviceOpenAnyService = remoteDeviceOpenAnyService;
this.remoteMqttBrokerOpenApi = remoteMqttBrokerOpenApi;
this.protocolMessageAdapter = protocolMessageAdapter;
}
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/TopicHandlerFactory.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/TopicHandlerFactory.java
index a5fc13c4..440bf519 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/TopicHandlerFactory.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/factory/TopicHandlerFactory.java
@@ -11,7 +11,7 @@
import java.util.regex.Pattern;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MQTT系统Topic 处理工厂类
* @packagename: com.mqttsnet.thinglinks.handler.factory
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/listener/MqttMessageListener.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/listener/MqttMessageListener.java
index 47a03a38..1e8af1b5 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/listener/MqttMessageListener.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/handler/listener/MqttMessageListener.java
@@ -10,7 +10,7 @@
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description:
* @packagename: com.mqttsnet.thinglinks.mqtt.handle.listener
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventActionService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventActionService.java
index 00073186..fabcd7b7 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventActionService.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventActionService.java
@@ -15,7 +15,7 @@
import java.util.Map;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MqttEventActionHandler
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventCommandService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventCommandService.java
index 21e2a06d..c8139b5a 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventCommandService.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventCommandService.java
@@ -7,7 +7,7 @@
import org.springframework.stereotype.Service;
/**
- * @program: thinglinks-cloud-pro-datasource-column
+ * @program: thinglinks
* @description: MqttEventCommandService
* @packagename: com.mqttsnet.thinglinks.mqtt.handler
* @author: ShiHuan Sun
diff --git a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventOtaCommandResponseService.java b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventOtaCommandResponseService.java
index 052e8083..6f3d98de 100644
--- a/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventOtaCommandResponseService.java
+++ b/thinglinks-modules/thinglinks-modules-broker/src/main/java/com/mqttsnet/thinglinks/broker/mqs/mqtt/service/MqttEventOtaCommandResponseService.java
@@ -2,7 +2,7 @@
import com.alibaba.fastjson.JSON;
import com.mqttsnet.thinglinks.common.core.domain.R;
-import com.mqttsnet.thinglinks.link.api.RemoteDeviceService;
+import com.mqttsnet.thinglinks.link.api.RemoteDeviceOpenAnyService;
import com.mqttsnet.thinglinks.link.api.domain.cache.device.DeviceCacheVO;
import com.mqttsnet.thinglinks.link.api.domain.vo.param.OtaCommandResponseParam;
import lombok.RequiredArgsConstructor;
@@ -35,7 +35,7 @@
public class MqttEventOtaCommandResponseService {
@Autowired
- private RemoteDeviceService remoteDeviceService;
+ private RemoteDeviceOpenAnyService remoteDeviceOpenAnyService;
/**
@@ -67,7 +67,7 @@ public void saveMqttEventOtaCommandResponse(DeviceCacheVO deviceCacheVO, String
// This is a placeholder for the actual saving logic
private void saveOtaCommandResponse(OtaCommandResponseParam responseParam) {
// Implementation for saving the response in your system
- R otaCommandResponseParamR = remoteDeviceService.saveUpgradeRecordByMqtt(responseParam);
+ R otaCommandResponseParamR = remoteDeviceOpenAnyService.saveUpgradeRecordByMqtt(responseParam);
log.info("otaCommandResponseParamR:{}", JSON.toJSONString(otaCommandResponseParamR));
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
index 194834c3..cfe3b7cf 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceController.java
@@ -14,14 +14,8 @@
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
import com.mqttsnet.thinglinks.link.api.domain.device.model.DeviceParams;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
-import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
-import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
import com.mqttsnet.thinglinks.link.service.device.DeviceService;
import com.mqttsnet.thinglinks.link.service.product.ProductService;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,7 +24,6 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -256,34 +249,6 @@ public ResponseEntity clientAuthentication(@RequestBody Map params) {
-
- final Object clientIdentifier = params.get("clientIdentifier");
- final Object username = params.get("username");
- final Object password = params.get("password");
- final Object deviceStatus = "ENABLE";// params.get("deviceStatus");
- final Object protocolType = "MQTT";// params.get("protocolType");
- Device device = deviceService.clientAuthentication(clientIdentifier.toString(), username.toString(), password.toString(), deviceStatus.toString(), protocolType.toString());
- log.info("{} 协议设备正在进行身份认证,客户端ID:{},用户名:{},密码:{},认证结果:{}", protocolType, clientIdentifier, username, password, device != null ? "成功" : "失败");
-
- Map resultValue = new HashMap<>();
- resultValue.put("clientId", clientIdentifier.toString());
- Map result = new HashMap<>();
- result.put("certificationResult", device == null ? false : true);
- result.put("tenantId", device == null ? "" : device.getAppId());
- result.put("deviceResult", resultValue);
-
- return ResponseEntity.ok().body(result);
- }
-
-
/**
* 根据客户端标识获取设备信息
*
@@ -314,166 +279,4 @@ public R> selectDeviceByDeviceIdentificationList(@RequestBody List dev
}
- /**
- * (MQTT)协议新增子设备档案
- *
- * @param topoAddSubDeviceParam 子设备参数
- * @return {@link TopoAddDeviceResultVO} 新增结果
- */
- @ApiOperation(value = "(MQTT)协议新增子设备档案", httpMethod = "POST", notes = "(MQTT)协议新增子设备档案")
- @PostMapping("/saveSubDeviceByMqtt")
- public R saveSubDeviceByMqtt(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam) {
- return R.ok(deviceService.saveSubDeviceByMqtt(topoAddSubDeviceParam));
- }
-
- /**
- * (HTTP)协议新增子设备档案
- *
- * @param topoAddSubDeviceParam 子设备参数
- * @return {@link TopoAddDeviceResultVO} 新增结果
- */
- @ApiOperation(value = "(HTTP)协议新增子设备档案", httpMethod = "POST", notes = "(HTTP)协议新增子设备档案")
- @PostMapping("/saveSubDeviceByHttp")
- public R saveSubDeviceByHttp(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam) {
- return R.ok(deviceService.saveSubDeviceByHttp(topoAddSubDeviceParam));
- }
-
- /**
- * MQTT协议修改子设备连接状态
- *
- * @param topoUpdateSubDeviceStatusParam 连接状态参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @ApiOperation(value = "(MQTT)协议修改子设备连接状态", httpMethod = "PUT", notes = "(MQTT)协议修改子设备连接状态")
- @PutMapping("/updateSubDeviceConnectStatusByMqtt")
- public R updateSubDeviceConnectStatusByMqtt(
- @RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
- TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.updateSubDeviceConnectStatusByMqtt(topoUpdateSubDeviceStatusParam);
- return R.ok(topoDeviceOperationResultVO);
- }
-
- /**
- * HTTP协议修改子设备连接状态
- *
- * @param topoUpdateSubDeviceStatusParam 连接状态参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @ApiOperation(value = "(HTTP)协议修改子设备连接状态", httpMethod = "PUT", notes = "(HTTP)协议修改子设备连接状态")
- @PutMapping("/updateSubDeviceConnectStatusByHttp")
- public R updateSubDeviceConnectStatusByHttp(
- @RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
- TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.updateSubDeviceConnectStatusByHttp(topoUpdateSubDeviceStatusParam);
- return R.ok(topoDeviceOperationResultVO);
- }
-
- /**
- * MQTT协议删除子设备
- *
- * @param topoDeleteSubDeviceParam 删除参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @ApiOperation(value = "(MQTT)协议删除子设备", httpMethod = "PUT", notes = "(MQTT)协议删除子设备")
- @PutMapping("/deleteSubDeviceByMqtt")
- public R deleteSubDeviceByMqtt(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
- TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deleteSubDeviceByMqtt(topoDeleteSubDeviceParam);
- return R.ok(topoDeviceOperationResultVO);
- }
-
- /**
- * HTTP协议删除子设备
- *
- * @param topoDeleteSubDeviceParam 删除参数
- * @return {@link TopoDeviceOperationResultVO} 修改结果
- */
- @ApiOperation(value = "(HTTP)协议删除子设备", httpMethod = "PUT", notes = "(HTTP)协议删除子设备")
- @PutMapping("/deleteSubDeviceByHttp")
- public R deleteSubDeviceByHttp(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
- TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deleteSubDeviceByHttp(topoDeleteSubDeviceParam);
- return R.ok(topoDeviceOperationResultVO);
- }
-
-
- /**
- * MQTT协议数据上报
- *
- * @param topoDeviceDataReportParam 数据上报参数
- * @return {@link TopoDeviceOperationResultVO} 上报结果
- */
- @ApiOperation(value = "(MQTT)协议数据上报", httpMethod = "POST", notes = "(MQTT)协议数据上报")
- @PostMapping("/deviceDataReportByMqtt")
- public R deviceDataReportByMqtt(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam) {
- TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deviceDataReportByMqtt(topoDeviceDataReportParam);
- return R.ok(topoDeviceOperationResultVO);
- }
-
- /**
- * HTTP协议数据上报
- *
- * @param topoDeviceDataReportParam 数据上报参数
- * @return {@link TopoDeviceOperationResultVO} 上报结果
- */
- @ApiOperation(value = "(HTTP)协议数据上报", httpMethod = "POST", notes = "(HTTP)协议数据上报")
- @PostMapping("/deviceDataReportByHttp")
- public R deviceDataReportByHttp(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam) {
- TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deviceDataReportByHttp(topoDeviceDataReportParam);
- return R.ok(topoDeviceOperationResultVO);
- }
-
- /**
- * Queries device information using the HTTP protocol.
- *
- * @param topoQueryDeviceParam The device query parameters.
- * @return {@link TopoQueryDeviceResultVO} The result of the device query.
- */
- @ApiOperation(value = "Query Device Information via HTTP Protocol", httpMethod = "POST", notes = "Queries device information using the HTTP protocol")
- @PostMapping("/queryDeviceByHttp")
- public R queryDeviceByHttp(@RequestBody TopoQueryDeviceParam topoQueryDeviceParam) {
- return R.ok(deviceService.queryDeviceByHttp(topoQueryDeviceParam));
- }
-
- /**
- * Receives and saves a new OTA upgrade record from an MQTT message. This endpoint
- * captures the command response parameters from the MQTT message body and persists them.
- *
- * @param otaCommandResponseParam The response parameters from an OTA command sent via MQTT.
- * @return {@link R} A response entity containing the saved OTA upgrade record.
- */
- @ApiOperation(value = "Save OTA Upgrade Record", httpMethod = "POST", notes = "Saves a new OTA upgrade record from MQTT message data.")
- @PostMapping("/saveOtaUpgradeRecordByMqtt")
- public R saveOtaUpgradeRecordByMqtt(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam) {
- try {
- // Call the service method to save the record
-// OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveOtaUpgradeRecordByMqtt(otaCommandResponseParam);
-
- // Return a successful response entity with the saved record
- return R.ok();
- } catch (Exception e) {
- // Log the exception and return an error response entity
- // Assuming R.fail() is a method to create a failure response
- return R.fail("Error saving OTA upgrade record: " + e.getMessage());
- }
- }
-
- /**
- * Receives and saves a new OTA upgrade record from an HTTP request. This endpoint
- * captures the command response parameters from the request body and persists them.
- *
- * @param otaCommandResponseParam The response parameters from an OTA command sent via HTTP.
- * @return {@link R} A response wrapper containing the saved OTA upgrade record.
- */
- @ApiOperation(value = "Save OTA Upgrade Record via HTTP", httpMethod = "POST", notes = "Saves a new OTA upgrade record from HTTP request data.")
- @PostMapping("/saveUpgradeRecordByHttp")
- public R saveUpgradeRecordByHttp(@Valid @RequestBody OtaCommandResponseParam otaCommandResponseParam) {
- try {
- // Call the service method to save the record
-// OtaCommandResponseParam savedRecord = otaUpgradeRecordsService.saveUpgradeRecordByHttp(otaCommandResponseParam);
-
- // Return a successful response wrapper with the saved record
- return R.ok();
- } catch (Exception e) {
- // Log the exception and return a failure response wrapper
- // Assuming R.fail() is a method to create a failure response
- return R.fail("Error saving OTA upgrade record via HTTP: " + e.getMessage());
- }
- }
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceInfoController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceInfoController.java
index d66c9f2a..313eba3d 100644
--- a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceInfoController.java
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceInfoController.java
@@ -28,8 +28,7 @@
*/
@RestController
@RequestMapping("/deviceInfo")
-public class DeviceInfoController extends BaseController
-{
+public class DeviceInfoController extends BaseController {
@Autowired
private DeviceInfoService deviceInfoService;
@@ -38,8 +37,7 @@ public class DeviceInfoController extends BaseController
*/
@PreAuthorize(hasPermi = "link:deviceInfo:list")
@GetMapping("/list")
- public TableDataInfo list(DeviceInfo deviceInfo)
- {
+ public TableDataInfo list(DeviceInfo deviceInfo) {
startPage();
List list = deviceInfoService.selectDeviceInfoList(deviceInfo);
return getDataTable(list);
@@ -51,8 +49,7 @@ public TableDataInfo list(DeviceInfo deviceInfo)
@PreAuthorize(hasPermi = "link:deviceInfo:export")
@Log(title = "子设备管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
- public void export(HttpServletResponse response, DeviceInfo deviceInfo) throws IOException
- {
+ public void export(HttpServletResponse response, DeviceInfo deviceInfo) throws IOException {
List list = deviceInfoService.selectDeviceInfoList(deviceInfo);
ExcelUtil util = new ExcelUtil(DeviceInfo.class);
util.exportExcel(response, list, "子设备管理数据");
@@ -63,8 +60,7 @@ public void export(HttpServletResponse response, DeviceInfo deviceInfo) throws I
*/
@PreAuthorize(hasPermi = "link:deviceInfo:query")
@GetMapping(value = "/{id}")
- public AjaxResult getInfo(@PathVariable("id") Long id)
- {
+ public AjaxResult getInfo(@PathVariable("id") Long id) {
return AjaxResult.success(deviceInfoService.selectDeviceInfoById(id));
}
@@ -74,8 +70,7 @@ public AjaxResult getInfo(@PathVariable("id") Long id)
@PreAuthorize(hasPermi = "link:deviceInfo:add")
@Log(title = "子设备管理", businessType = BusinessType.INSERT)
@PostMapping
- public AjaxResult add(@RequestBody @Valid DeviceInfoParams deviceInfoParams)
- {
+ public AjaxResult add(@RequestBody @Valid DeviceInfoParams deviceInfoParams) {
return toAjax(deviceInfoService.insertDeviceInfo(deviceInfoParams));
}
@@ -85,8 +80,7 @@ public AjaxResult add(@RequestBody @Valid DeviceInfoParams deviceInfoParams)
@PreAuthorize(hasPermi = "link:deviceInfo:edit")
@Log(title = "子设备管理", businessType = BusinessType.UPDATE)
@PutMapping
- public AjaxResult edit(@RequestBody @Valid DeviceInfoParams deviceInfoParams)
- {
+ public AjaxResult edit(@RequestBody @Valid DeviceInfoParams deviceInfoParams) {
return toAjax(deviceInfoService.updateDeviceInfo(deviceInfoParams));
}
@@ -96,20 +90,19 @@ public AjaxResult edit(@RequestBody @Valid DeviceInfoParams deviceInfoParams)
@PreAuthorize(hasPermi = "link:deviceInfo:remove")
@Log(title = "子设备管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
- public AjaxResult remove(@PathVariable("ids") Long[] ids)
- {
+ public AjaxResult remove(@PathVariable("ids") Long[] ids) {
return toAjax(deviceInfoService.deleteDeviceInfoByIds(ids));
}
/**
* 查询子设备影子数据
+ *
* @param params
* @return
*/
@PreAuthorize(hasPermi = "link:deviceInfo:shadow")
@PostMapping(value = "/getDeviceInfoShadow")
- public AjaxResult getDeviceInfoShadow(@RequestBody Map params)
- {
+ public AjaxResult getDeviceInfoShadow(@RequestBody Map params) {
final Object ids = params.get("ids");
final Object startTime = params.get("startTime");
final Object endTime = params.get("endTime");
@@ -118,14 +111,15 @@ public AjaxResult getDeviceInfoShadow(@RequestBody Map params)
/**
* 刷新子设备数据模型
+ *
* @param ids
* @return
*/
@PreAuthorize(hasPermi = "link:deviceInfo:initialize")
@GetMapping("/refreshDeviceInfoDataModel/{ids}")
- public AjaxResult refreshDeviceInfoDataModel(@PathVariable("ids") Long[] ids)
- {
+ public AjaxResult refreshDeviceInfoDataModel(@PathVariable("ids") Long[] ids) {
return toAjax(deviceInfoService.refreshDeviceInfoDataModel(Arrays.asList(ids)));
}
+
}
diff --git a/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceOpenAnyController.java b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceOpenAnyController.java
new file mode 100644
index 00000000..a82dc9fe
--- /dev/null
+++ b/thinglinks-modules/thinglinks-modules-link/src/main/java/com/mqttsnet/thinglinks/link/controller/device/DeviceOpenAnyController.java
@@ -0,0 +1,256 @@
+
+package com.mqttsnet.thinglinks.link.controller.device;
+
+import com.mqttsnet.thinglinks.common.core.constant.Constants;
+import com.mqttsnet.thinglinks.common.core.domain.R;
+import com.mqttsnet.thinglinks.common.core.web.controller.BaseController;
+import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
+import com.mqttsnet.thinglinks.link.api.domain.vo.param.*;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoAddDeviceResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoDeviceOperationResultVO;
+import com.mqttsnet.thinglinks.link.api.domain.vo.result.TopoQueryDeviceResultVO;
+import com.mqttsnet.thinglinks.link.service.device.DeviceInfoService;
+import com.mqttsnet.thinglinks.link.service.device.DeviceService;
+import com.mqttsnet.thinglinks.link.service.product.ProductService;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 设备管理开放Controller
+ * 用于设备接入协议通用入口
+ *
+ * @author thinglinks
+ * @date 2024-03-22
+ */
+@RestController
+@RequestMapping("/deviceOpenAny")
+@Slf4j
+public class DeviceOpenAnyController extends BaseController {
+ @Autowired
+ private DeviceService deviceService;
+ @Autowired
+ private DeviceInfoService deviceInfoService;
+ @Autowired
+ private ProductService productService;
+
+
+ /**
+ * 客户端连接认证
+ *
+ * @param request
+ * @param params clientIdentifier 客户端标识
+ * username 用户名
+ * password 密码
+ * authMode 认证方式
+ * protocolType 协议类型
+ * @return 认证结果
+ */
+ @RequestMapping("/clientConnectionAuthentication")
+ public ResponseEntity clientConnectionAuthentication(HttpServletRequest request, @RequestBody Map params) {
+
+ final Object clientIdentifier = params.get("clientIdentifier");
+ final Object username = params.get("username");
+ final Object password = params.get("password");
+ final Object deviceStatus = "ENABLE";// params.get("deviceStatus");
+ final Object protocolType = "MQTT";// params.get("protocolType");
+ Device device = deviceService.clientAuthentication(clientIdentifier.toString(), username.toString(), password.toString(), deviceStatus.toString(), protocolType.toString());
+ log.info("{} 协议设备正在进行身份认证,客户端ID:{},用户名:{},密码:{},认证结果:{}", protocolType, clientIdentifier, username, password, device != null ? "成功" : "失败");
+
+ Map result = new HashMap<>();
+ result.put("certificationResult", device != null);
+ result.put("tenantId", device == null ? Constants.PROJECT_PREFIX : device.getAppId());
+
+ Map resultValue = new HashMap<>();
+ resultValue.put("clientId", clientIdentifier.toString());
+ result.put("deviceResult", resultValue);
+
+ return ResponseEntity.ok().body(result);
+ }
+
+
+ /**
+ * (MQTT)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @ApiOperation(value = "(MQTT)协议新增子设备档案", httpMethod = "POST", notes = "(MQTT)协议新增子设备档案")
+ @PostMapping("/saveSubDeviceByMqtt")
+ public R saveSubDeviceByMqtt(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return R.ok(deviceInfoService.saveSubDeviceByMqtt(topoAddSubDeviceParam));
+ }
+
+ /**
+ * (HTTP)协议新增子设备档案
+ *
+ * @param topoAddSubDeviceParam 子设备参数
+ * @return {@link TopoAddDeviceResultVO} 新增结果
+ */
+ @ApiOperation(value = "(HTTP)协议新增子设备档案", httpMethod = "POST", notes = "(HTTP)协议新增子设备档案")
+ @PostMapping("/saveSubDeviceByHttp")
+ public R saveSubDeviceByHttp(@RequestBody TopoAddSubDeviceParam topoAddSubDeviceParam) {
+ return R.ok(deviceInfoService.saveSubDeviceByHttp(topoAddSubDeviceParam));
+ }
+
+ /**
+ * MQTT协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(MQTT)协议修改子设备连接状态", httpMethod = "PUT", notes = "(MQTT)协议修改子设备连接状态")
+ @PutMapping("/updateSubDeviceConnectStatusByMqtt")
+ public R updateSubDeviceConnectStatusByMqtt(
+ @RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceInfoService.updateSubDeviceConnectStatusByMqtt(topoUpdateSubDeviceStatusParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * HTTP协议修改子设备连接状态
+ *
+ * @param topoUpdateSubDeviceStatusParam 连接状态参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(HTTP)协议修改子设备连接状态", httpMethod = "PUT", notes = "(HTTP)协议修改子设备连接状态")
+ @PutMapping("/updateSubDeviceConnectStatusByHttp")
+ public R updateSubDeviceConnectStatusByHttp(
+ @RequestBody @ApiParam(value = "连接状态参数") TopoUpdateSubDeviceStatusParam topoUpdateSubDeviceStatusParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceInfoService.updateSubDeviceConnectStatusByHttp(topoUpdateSubDeviceStatusParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * MQTT协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(MQTT)协议删除子设备", httpMethod = "PUT", notes = "(MQTT)协议删除子设备")
+ @PutMapping("/deleteSubDeviceByMqtt")
+ public R deleteSubDeviceByMqtt(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceInfoService.deleteSubDeviceByMqtt(topoDeleteSubDeviceParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * HTTP协议删除子设备
+ *
+ * @param topoDeleteSubDeviceParam 删除参数
+ * @return {@link TopoDeviceOperationResultVO} 修改结果
+ */
+ @ApiOperation(value = "(HTTP)协议删除子设备", httpMethod = "PUT", notes = "(HTTP)协议删除子设备")
+ @PutMapping("/deleteSubDeviceByHttp")
+ public R deleteSubDeviceByHttp(@RequestBody @ApiParam(value = "删除参数") TopoDeleteSubDeviceParam topoDeleteSubDeviceParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceInfoService.deleteSubDeviceByHttp(topoDeleteSubDeviceParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+
+ /**
+ * MQTT协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @ApiOperation(value = "(MQTT)协议数据上报", httpMethod = "POST", notes = "(MQTT)协议数据上报")
+ @PostMapping("/deviceDataReportByMqtt")
+ public R deviceDataReportByMqtt(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deviceDataReportByMqtt(topoDeviceDataReportParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * HTTP协议数据上报
+ *
+ * @param topoDeviceDataReportParam 数据上报参数
+ * @return {@link TopoDeviceOperationResultVO} 上报结果
+ */
+ @ApiOperation(value = "(HTTP)协议数据上报", httpMethod = "POST", notes = "(HTTP)协议数据上报")
+ @PostMapping("/deviceDataReportByHttp")
+ public R deviceDataReportByHttp(@RequestBody @ApiParam(value = "数据上报参数") TopoDeviceDataReportParam topoDeviceDataReportParam) {
+ TopoDeviceOperationResultVO topoDeviceOperationResultVO = deviceService.deviceDataReportByHttp(topoDeviceDataReportParam);
+ return R.ok(topoDeviceOperationResultVO);
+ }
+
+ /**
+ * Queries device information using the MQTT protocol.
+ *
+ * @param topoQueryDeviceParam The device query parameters.
+ * @return {@link TopoQueryDeviceResultVO} The result of the device query.
+ */
+ @ApiOperation(value = "Query Device Information via MQTT Protocol", httpMethod = "POST", notes = "Queries device information using the MQTT protocol")
+ @PostMapping("/deviceOpenAny/queryDeviceByMqtt")
+ public R