|
@@ -3,17 +3,25 @@ package com.middle.platform.manage.biz.service;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.middle.platform.common.constant.Global;
|
|
import com.middle.platform.common.constant.Global;
|
|
|
import com.middle.platform.common.exception.BusinessException;
|
|
import com.middle.platform.common.exception.BusinessException;
|
|
|
|
|
+import com.middle.platform.data.api.constant.TopicType;
|
|
|
import com.middle.platform.data.api.feign.DynamicTopicApi;
|
|
import com.middle.platform.data.api.feign.DynamicTopicApi;
|
|
|
|
|
+import com.middle.platform.data.api.pojo.TopicDto;
|
|
|
import com.middle.platform.manage.biz.constant.UrlCategory;
|
|
import com.middle.platform.manage.biz.constant.UrlCategory;
|
|
|
import com.middle.platform.manage.biz.constant.UrlInit;
|
|
import com.middle.platform.manage.biz.constant.UrlInit;
|
|
|
import com.middle.platform.manage.biz.constant.UrlProtocol;
|
|
import com.middle.platform.manage.biz.constant.UrlProtocol;
|
|
|
|
|
+import com.middle.platform.manage.biz.constant.UrlType;
|
|
|
import com.middle.platform.manage.biz.domain.req.IotUrlPara;
|
|
import com.middle.platform.manage.biz.domain.req.IotUrlPara;
|
|
|
import com.middle.platform.manage.biz.entity.IotProduct;
|
|
import com.middle.platform.manage.biz.entity.IotProduct;
|
|
|
import com.middle.platform.manage.biz.entity.IotUrl;
|
|
import com.middle.platform.manage.biz.entity.IotUrl;
|
|
|
import com.middle.platform.manage.biz.mapper.IotUrlMapper;
|
|
import com.middle.platform.manage.biz.mapper.IotUrlMapper;
|
|
|
|
|
+import com.middle.platform.redis.service.CacheService;
|
|
|
|
|
+import jakarta.annotation.Resource;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.Objects;
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -24,7 +32,60 @@ import java.util.Objects;
|
|
|
@RequiredArgsConstructor
|
|
@RequiredArgsConstructor
|
|
|
public class IotUrlService {
|
|
public class IotUrlService {
|
|
|
private final IotUrlMapper iotUrlMapper;
|
|
private final IotUrlMapper iotUrlMapper;
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private IotProductService iotProductService;
|
|
|
private final DynamicTopicApi dynamicTopicApi;
|
|
private final DynamicTopicApi dynamicTopicApi;
|
|
|
|
|
+ private final CacheService cacheService;
|
|
|
|
|
+ private String topicPrefix = "/iot/%s/+/";
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 校验topic
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iotUrlPara
|
|
|
|
|
+ */
|
|
|
|
|
+ private void checkTopic(IotUrlPara iotUrlPara) {
|
|
|
|
|
+ //校验前缀是否为 /iot/{productKey}/*/
|
|
|
|
|
+ IotProduct query = iotProductService.query(iotUrlPara.getProductId());
|
|
|
|
|
+ if (Objects.isNull(query)) {
|
|
|
|
|
+ throw new BusinessException("产品不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ //产品key
|
|
|
|
|
+ String code = query.getCode();
|
|
|
|
|
+ if (!StringUtils.startsWith(iotUrlPara.getUrl(), String.format(topicPrefix, code))) {
|
|
|
|
|
+ throw new BusinessException("topic必须以+" + String.format(topicPrefix, code) + "为前缀");
|
|
|
|
|
+ }
|
|
|
|
|
+ //todo topic合规校验
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 订阅地址,添加缓存
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param url topic地址
|
|
|
|
|
+ * @param func func+permission
|
|
|
|
|
+ */
|
|
|
|
|
+ private void subUrl(String url, String func) {
|
|
|
|
|
+ ThreadTask.addJob(() -> {
|
|
|
|
|
+ //订阅topic
|
|
|
|
|
+ dynamicTopicApi.saveTopic(new TopicDto(url, 0));
|
|
|
|
|
+ //写入 CacheConstant.TOPIC_CACHE缓存
|
|
|
|
|
+ cacheService.setTopic(url, func);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 取消订阅的topic,并删除缓存的topic
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param url
|
|
|
|
|
+ */
|
|
|
|
|
+ private void removeUrl(String url) {
|
|
|
|
|
+ ThreadTask.addJob(() -> {
|
|
|
|
|
+ dynamicTopicApi.removeTopic(new TopicDto(url, 0));
|
|
|
|
|
+ //删除原topic
|
|
|
|
|
+ cacheService.delTopic(url);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 新增topic
|
|
* 新增topic
|
|
@@ -32,10 +93,10 @@ public class IotUrlService {
|
|
|
* @param iotUrlPara
|
|
* @param iotUrlPara
|
|
|
* @return
|
|
* @return
|
|
|
*/
|
|
*/
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
public Object saveUrl(IotUrlPara iotUrlPara) {
|
|
public Object saveUrl(IotUrlPara iotUrlPara) {
|
|
|
- if (Objects.isNull(iotUrlPara.getProductId())) {
|
|
|
|
|
- throw new BusinessException("产品id不能为空");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ //topi规则校验
|
|
|
|
|
+ checkTopic(iotUrlPara);
|
|
|
IotUrl iotUrl = new IotUrl();
|
|
IotUrl iotUrl = new IotUrl();
|
|
|
iotUrl.setProductId(iotUrlPara.getProductId());
|
|
iotUrl.setProductId(iotUrlPara.getProductId());
|
|
|
iotUrl.setCategory(iotUrlPara.getCategory());
|
|
iotUrl.setCategory(iotUrlPara.getCategory());
|
|
@@ -46,20 +107,31 @@ public class IotUrlService {
|
|
|
iotUrl.setRemark(iotUrlPara.getRemark());
|
|
iotUrl.setRemark(iotUrlPara.getRemark());
|
|
|
iotUrlMapper.insert(iotUrl);
|
|
iotUrlMapper.insert(iotUrl);
|
|
|
//新增订阅的topic
|
|
//新增订阅的topic
|
|
|
-// dynamicTopicApi
|
|
|
|
|
|
|
+ if (Objects.equals(iotUrlPara.getType(), UrlType.MQTT)
|
|
|
|
|
+ && (Objects.equals(iotUrlPara.getPermission(), TopicType.PUB) || Objects.equals(iotUrlPara.getPermission(), TopicType.BOTH))) {
|
|
|
|
|
+ subUrl(iotUrl.getUrl(), iotUrl.getFunc() + String.valueOf(iotUrl.getPermission()));
|
|
|
|
|
+ }
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 修改topic
|
|
* 修改topic
|
|
|
*
|
|
*
|
|
|
* @param iotUrlPara
|
|
* @param iotUrlPara
|
|
|
* @return
|
|
* @return
|
|
|
*/
|
|
*/
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
public Object update(IotUrlPara iotUrlPara) {
|
|
public Object update(IotUrlPara iotUrlPara) {
|
|
|
if (Objects.isNull(iotUrlPara.getId())) {
|
|
if (Objects.isNull(iotUrlPara.getId())) {
|
|
|
throw new BusinessException("id不能为空");
|
|
throw new BusinessException("id不能为空");
|
|
|
}
|
|
}
|
|
|
|
|
+ checkTopic(iotUrlPara);
|
|
|
|
|
+ IotUrl iotUrlCheck = iotUrlMapper.selectById(iotUrlPara.getId());
|
|
|
|
|
+ if (Objects.isNull(iotUrlCheck)) {
|
|
|
|
|
+ throw new BusinessException("设备不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
IotUrl iotUrl = new IotUrl();
|
|
IotUrl iotUrl = new IotUrl();
|
|
|
iotUrl.setId(iotUrlPara.getId());
|
|
iotUrl.setId(iotUrlPara.getId());
|
|
|
iotUrl.setCategory(iotUrlPara.getCategory());
|
|
iotUrl.setCategory(iotUrlPara.getCategory());
|
|
@@ -69,6 +141,11 @@ public class IotUrlService {
|
|
|
iotUrl.setType(iotUrlPara.getType());
|
|
iotUrl.setType(iotUrlPara.getType());
|
|
|
iotUrl.setRemark(iotUrlPara.getRemark());
|
|
iotUrl.setRemark(iotUrlPara.getRemark());
|
|
|
iotUrlMapper.updateById(iotUrl);
|
|
iotUrlMapper.updateById(iotUrl);
|
|
|
|
|
+ //取消订阅原topic 订阅topic
|
|
|
|
|
+ if (Objects.equals(iotUrlPara.getType(), UrlType.MQTT) && (Objects.equals(iotUrlPara.getPermission(), TopicType.PUB) || Objects.equals(iotUrlPara.getPermission(), TopicType.BOTH))) {
|
|
|
|
|
+ removeUrl(iotUrlCheck.getUrl());
|
|
|
|
|
+ subUrl(iotUrl.getUrl(), iotUrl.getFunc() + String.valueOf(iotUrl.getPermission()));
|
|
|
|
|
+ }
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -79,7 +156,18 @@ public class IotUrlService {
|
|
|
* @return
|
|
* @return
|
|
|
*/
|
|
*/
|
|
|
public Object remove(Long id) {
|
|
public Object remove(Long id) {
|
|
|
- iotUrlMapper.deleteById(id);
|
|
|
|
|
|
|
+ IotUrl iotUrlCheck = iotUrlMapper.selectById(id);
|
|
|
|
|
+ if (Objects.isNull(iotUrlCheck)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ IotUrl iotUrl = new IotUrl();
|
|
|
|
|
+ iotUrl.setDeleteTime(LocalDateTime.now());
|
|
|
|
|
+ iotUrl.setDelFlag(Global.DEL);
|
|
|
|
|
+ iotUrlMapper.update(iotUrl, new LambdaQueryWrapper<IotUrl>().eq(IotUrl::getId, id).eq(IotUrl::getDelFlag, Global.UN_DEL));
|
|
|
|
|
+ //取消订阅
|
|
|
|
|
+ if (Objects.equals(iotUrlCheck.getType(), UrlType.MQTT) && (Objects.equals(iotUrlCheck.getPermission(), TopicType.PUB) || Objects.equals(iotUrlCheck.getPermission(), TopicType.BOTH))) {
|
|
|
|
|
+ removeUrl(iotUrlCheck.getUrl());
|
|
|
|
|
+ }
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -91,7 +179,7 @@ public class IotUrlService {
|
|
|
* @return
|
|
* @return
|
|
|
*/
|
|
*/
|
|
|
public Object getUrl(Long productId, Integer type) {
|
|
public Object getUrl(Long productId, Integer type) {
|
|
|
- return iotUrlMapper.selectList(new LambdaQueryWrapper<IotUrl>().eq(IotUrl::getProductId, productId).eq(IotUrl::getType, type));
|
|
|
|
|
|
|
+ return iotUrlMapper.selectList(new LambdaQueryWrapper<IotUrl>().eq(IotUrl::getProductId, productId).eq(IotUrl::getType, type).eq(IotUrl::getDelFlag, Global.UN_DEL));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -112,9 +200,13 @@ public class IotUrlService {
|
|
|
iotUrl.setType(iotProduct.getReportProtocol());
|
|
iotUrl.setType(iotProduct.getReportProtocol());
|
|
|
iotUrl.setRemark(value.getDesc());
|
|
iotUrl.setRemark(value.getDesc());
|
|
|
iotUrlMapper.insert(iotUrl);
|
|
iotUrlMapper.insert(iotUrl);
|
|
|
|
|
+ subUrl(iotUrl.getUrl(), iotUrl.getFunc() + String.valueOf(iotUrl.getPermission()));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ //http
|
|
|
|
|
+ if (Objects.equals(iotProduct.getReportProtocol(), UrlProtocol.HTTP)) {
|
|
|
|
|
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|