增加事件发布相关代码,用来对接盐城与南京的数据传输,未验证

master
Terry 2 weeks ago
parent 696de12073
commit 41f2a8b5ea

@ -80,10 +80,10 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
return new Paging<>(count, ruleLogs.stream().map(r -> return new Paging<>(count, ruleLogs.stream().map(r ->
new ThingModelMessage(r.getTime().toString(), r.getMid(), new ThingModelMessage(r.getTime().toString(), r.getMid(),
deviceId, r.getProductKey(), r.getDeviceName(), deviceId, r.getProductKey(), r.getDeviceName(),
r.getUid(), r.getType(),r.getIdentifier(),r.getDeviceStatus(), r.getCode(), r.getUid(), r.getType(),r.getIdentifier(),r.getCode(),
JsonUtils.parseObject(r.getData(), Map.class), JsonUtils.parseObject(r.getData(), Map.class),
r.getTime(), r.getReportTime())) r.getTime(), r.getReportTime()))
.collect(Collectors.toList())); .collect(Collectors.toList()));//r.getDeviceStatus(),
} }
@Override @Override
@ -120,7 +120,7 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
return new Paging<>(count, ruleLogs.stream().map(r -> return new Paging<>(count, ruleLogs.stream().map(r ->
new ThingModelMessage(r.getTime().toString(), r.getMid(), new ThingModelMessage(r.getTime().toString(), r.getMid(),
r.getDeviceId(), r.getProductKey(), r.getDeviceName(), r.getDeviceId(), r.getProductKey(), r.getDeviceName(),
r.getUid(), r.getType(), r.getIdentifier(),r.getDeviceStatus(), r.getCode(), r.getUid(), r.getType(), r.getIdentifier(), r.getCode(),
JsonUtils.parseObject(r.getData(), Map.class), JsonUtils.parseObject(r.getData(), Map.class),
r.getTime(), r.getReportTime())) r.getTime(), r.getReportTime()))
.collect(Collectors.toList())); .collect(Collectors.toList()));

@ -93,7 +93,12 @@ public class OtaService {
} }
String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length()); String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length());
//OssClient storage = OssFactory.instance(); //OssClient storage = OssFactory.instance();
String url = minioUtil.upload(file); String url;
try {
url = minioUtil.upload(file.getBytes(), file.getOriginalFilename(), file.getContentType());
} catch (IOException e) {
throw new BizException("文件上传失败: " + e.getMessage());
}
// uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); // uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
// 保存文件信息 // 保存文件信息

@ -40,6 +40,7 @@ import cc.iotkit.data.dao.DeviceInfoRepository;
import cc.iotkit.data.manager.*; import cc.iotkit.data.manager.*;
import cc.iotkit.data.model.TbDeviceInfo; import cc.iotkit.data.model.TbDeviceInfo;
import cc.iotkit.data.system.ISysDeptData; import cc.iotkit.data.system.ISysDeptData;
import cc.iotkit.manager.event.DeviceSyncEvent;
import cc.iotkit.manager.dto.bo.device.*; import cc.iotkit.manager.dto.bo.device.*;
import cc.iotkit.manager.dto.bo.devicegroup.DeviceAddGroupBo; import cc.iotkit.manager.dto.bo.devicegroup.DeviceAddGroupBo;
import cc.iotkit.manager.dto.bo.devicegroup.DeviceGroupBo; import cc.iotkit.manager.dto.bo.devicegroup.DeviceGroupBo;
@ -77,6 +78,7 @@ import me.chanjar.weixin.common.bean.subscribemsg.CategoryData;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -139,6 +141,10 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService {
@Qualifier("categoryDataCache") @Qualifier("categoryDataCache")
private ICategoryData categoryData; private ICategoryData categoryData;
//用来发布设备信息同步事件
@Autowired
private ApplicationEventPublisher eventPublisher;
@Override @Override
public Paging<DeviceInfoVo> getDevices(PageRequest<DeviceQueryBo> pageRequest) { public Paging<DeviceInfoVo> getDevices(PageRequest<DeviceQueryBo> pageRequest) {
DeviceQueryBo query = pageRequest.getData(); DeviceQueryBo query = pageRequest.getData();
@ -306,6 +312,8 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService {
TenantHelper.enableIgnore(); TenantHelper.enableIgnore();
deviceInfoData.save(device); deviceInfoData.save(device);
eventPublisher.publishEvent(new DeviceSyncEvent(this,"create",device));
return true; return true;
} }
@ -355,14 +363,23 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService {
@Override @Override
public boolean deleteDevice(String deviceId) { public boolean deleteDevice(String deviceId) {
deviceId = getDetail(deviceId).getDeviceId(); DeviceInfo device = deviceInfoData.findByDeviceId(deviceId);
deviceId = device.getDeviceId();
deviceInfoData.deleteById(deviceId); deviceInfoData.deleteById(deviceId);
if (device != null) {
eventPublisher.publishEvent(new DeviceSyncEvent(this, "delete", device));
}
return true; return true;
} }
@Override @Override
public boolean batchDeleteDevice(List<String> ids) { public boolean batchDeleteDevice(List<String> ids) {
deviceInfoData.deleteByIds(ids); deviceInfoData.deleteByIds(ids);
//TODO 批量删除时发出事件
return true; return true;
} }
@ -637,7 +654,14 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService {
}*/ }*/
// iSystemData.findById(); // iSystemData.findById();
TenantHelper.enableIgnore(); TenantHelper.enableIgnore();
return deviceInfoData.save(di) != null;
var res=deviceInfoData.save(di);
if(res!=null){
eventPublisher.publishEvent(new DeviceSyncEvent(this, "update", di));
}
return res != null;
} }
public static Map<String, DeviceInfo.Group> convert(Object obj) { public static Map<String, DeviceInfo.Group> convert(Object obj) {
@ -692,7 +716,14 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService {
// di.setId(data.getId()); // di.setId(data.getId());
TenantHelper.enableIgnore(); TenantHelper.enableIgnore();
return deviceInfoData.save(deviceInfo) != null;
var res=deviceInfoData.save(deviceInfo);
if(res!=null){
eventPublisher.publishEvent(new DeviceSyncEvent(this, "update", deviceInfo));
}
return res != null;
// return deviceInfoData.save(deviceInfo) != null;
} }
@Override @Override
@ -714,7 +745,15 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService {
if (ObjectUtil.isNotNull(deviceRepetition.getUid()) && !deviceRepetition.getUid().equals(di.getUid())) { if (ObjectUtil.isNotNull(deviceRepetition.getUid()) && !deviceRepetition.getUid().equals(di.getUid())) {
throw new BizException("设备已绑定"); throw new BizException("设备已绑定");
} }
return deviceInfoData.save(di) != null;
var res=deviceInfoData.save(di);
if(res!=null){
eventPublisher.publishEvent(new DeviceSyncEvent(this, "update", di));
}
return res != null;
// return deviceInfoData.save(di) != null;
} }
@Override @Override

@ -39,11 +39,13 @@ import cc.iotkit.openapi.dto.bo.device.OpenapiDeviceBo;
import cc.iotkit.openapi.dto.vo.OpenDeviceInfoVo; import cc.iotkit.openapi.dto.vo.OpenDeviceInfoVo;
import cc.iotkit.openapi.dto.vo.OpenDevicePropertyVo; import cc.iotkit.openapi.dto.vo.OpenDevicePropertyVo;
import cc.iotkit.openapi.dto.vo.OpenPropertyVo; import cc.iotkit.openapi.dto.vo.OpenPropertyVo;
import cc.iotkit.manager.event.DeviceSyncEvent;
import cc.iotkit.openapi.service.OpenDeviceService; import cc.iotkit.openapi.service.OpenDeviceService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
@ -69,6 +71,9 @@ public class OpenDeviceServiceImpl implements OpenDeviceService {
@Autowired @Autowired
private DeviceCtrlService deviceCtrlService; private DeviceCtrlService deviceCtrlService;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Override @Override
public DeviceInfo getDetail(OpenapiDeviceBo data) { public DeviceInfo getDetail(OpenapiDeviceBo data) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceName(data.getDeviceName()); DeviceInfo deviceInfo = deviceInfoData.findByDeviceName(data.getDeviceName());
@ -113,6 +118,9 @@ public class OpenDeviceServiceImpl implements OpenDeviceService {
device.setParentId(parentId); device.setParentId(parentId);
} }
deviceInfoData.save(device); deviceInfoData.save(device);
eventPublisher.publishEvent(new DeviceSyncEvent(this, "create", device));
return MapstructUtils.convert(device, OpenDeviceInfoVo.class); return MapstructUtils.convert(device, OpenDeviceInfoVo.class);
} }
@ -123,6 +131,8 @@ public class OpenDeviceServiceImpl implements OpenDeviceService {
throw new BizException(ErrCode.DEVICE_NOT_FOUND); throw new BizException(ErrCode.DEVICE_NOT_FOUND);
} }
deviceInfoData.deleteById(deviceRepetition.getDeviceId()); deviceInfoData.deleteById(deviceRepetition.getDeviceId());
eventPublisher.publishEvent(new DeviceSyncEvent(this, "delete", deviceRepetition));
return true; return true;
} }

@ -0,0 +1,24 @@
package cc.iotkit.openapi.sync;
import cc.iotkit.manager.event.DeviceSyncEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class DeviceSyncEventListener {
private final DeviceSyncService syncService;
@Async
@EventListener(DeviceSyncEvent.class)
public void onDeviceSync(DeviceSyncEvent event){
log.info("接手到设备同步事件,operation={},deviceId={}",
event.getOperation(),
event.getDevice() != null ? event.getDevice().getDeviceId() : "null");
syncService.sync(event);
}
}

@ -0,0 +1,150 @@
package cc.iotkit.openapi.sync;
import cc.iotkit.manager.config.DeviceSyncConfig;
import cc.iotkit.manager.event.DeviceSyncEvent;
import cc.iotkit.system.dto.vo.SysTenantVo;
import cc.iotkit.system.service.ISysTenantService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Service;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceSyncService {
private final DeviceSyncConfig config;
private final ObjectMapper objectMapper;
private final ISysTenantService sysTenantService;
private final OkHttpClient httpClient = new OkHttpClient.Builder().build();
public void sync(DeviceSyncEvent event) {
if (!config.isEnable()) {
log.info("设备同步功能未启用跳过同步operation={}, deviceId={}",
event.getOperation(), event.getDevice().getDeviceId());
return;
}
int maxRetry = config.getRetry();
for (int i = 0; i < maxRetry; i++) {
try {
doSync(event);
log.info("同步设备信息成功operation={}, deviceId={}",
event.getOperation(), event.getDevice().getDeviceId());
return;
} catch (Exception e) {
log.warn("同步设备信息失败,第{}次:{}", (i + 1), e.getMessage());
if (i == maxRetry - 1) {
log.error("同步设备信息失败已达重试上限operation={}, deviceId={}",
event.getOperation(), event.getDevice().getDeviceId(), e);
}
}
}
}
private void doSync(DeviceSyncEvent event) throws Exception {
String deviceId = event.getDevice().getDeviceId();
String token = encrypt(deviceId, config.getEncryptKey());
if ("delete".equals(event.getOperation())) {
doDelete(deviceId, token);
} else {
doAddOrEdit(event, deviceId, token);
}
}
private void doDelete(String deviceId, String token) throws Exception {
String url = config.getDeleteUrl() + "?deviceCode=" + deviceId + "&token=" + token;
log.info("删除设备请求url={}", url);
Request request = new Request.Builder()
.url(url)
.get()
.build();
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new RuntimeException("删除设备失败HTTP " + response.code());
}
}
}
private void doAddOrEdit(DeviceSyncEvent event, String deviceId, String token) throws Exception {
Map<String, Object> body = new HashMap<>();
body.put("deviceCode", deviceId);
body.put("token", token);
body.put("deviceModel", event.getDevice().getModel());
body.put("longitude", event.getDevice().getLongitude());
body.put("latitude", event.getDevice().getLatitude());
body.put("districtName", "");
body.put("dockingCompany", config.getDockingCompany());
body.put("deviceAddress", event.getDevice().getSite());
Long tenantId = event.getDevice().getTenantId();
if (tenantId != null) {
try {
SysTenantVo tenant = sysTenantService.queryByTenantId(tenantId);
if (tenant != null) {
body.put("enterpriseName", tenant.getCompanyName());
body.put("enterpriseUser", tenant.getContactUserName());
body.put("phone", tenant.getContactPhone());
} else {
log.warn("租户信息为空tenantId={}", tenantId);
body.put("enterpriseName", "");
body.put("enterpriseUser", "");
body.put("phone", "");
}
} catch (Exception e) {
log.warn("查询租户信息异常tenantId={}, error={}", tenantId, e.getMessage());
body.put("enterpriseName", "");
body.put("enterpriseUser", "");
body.put("phone", "");
}
} else {
body.put("enterpriseName", "");
body.put("enterpriseUser", "");
body.put("phone", "");
}
body.put("enterpriseUser1", "");
body.put("phone1", "");
body.put("enterpriseUser2", "");
body.put("phone2", "");
log.info("同步设备请求operation={}, url={}, body={}",
event.getOperation(), config.getDeviceUrl(), body);
Request request = new Request.Builder()
.url(config.getDeviceUrl())
.post(RequestBody.create(objectMapper.writeValueAsString(body),
MediaType.parse("application/json")))
.build();
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new RuntimeException("同步设备失败HTTP " + response.code());
}
}
}
public static String encrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes(StandardCharsets.UTF_8));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return java.util.Base64.getEncoder().encodeToString(cipher.doFinal(message.getBytes(StandardCharsets.UTF_8)));
}
}

@ -224,7 +224,8 @@ public class ThingServiceImpl implements IThingService {
.identifier(ThingModelMessage.ID_PROPERTY_REPORT) .identifier(ThingModelMessage.ID_PROPERTY_REPORT)
.data(propertyReport.getParams()) .data(propertyReport.getParams())
.time(propertyReport.getTime()) .time(propertyReport.getTime())
.deviceStatus(device.getDeviceStatus()) // 注释原因ThingModelMessage 核心类中不存在 deviceStatus 字段,调用会导致编译失败
// .deviceStatus(device.getDeviceStatus())
.occurred(propertyReport.getTime()) .occurred(propertyReport.getTime())
.build() .build()
); );
@ -366,7 +367,8 @@ public class ThingServiceImpl implements IThingService {
.deviceName(device.getDeviceName()) .deviceName(device.getDeviceName())
.productKey(device.getProductKey()) .productKey(device.getProductKey())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.deviceStatus(device.getDeviceStatus()) // 注释原因ThingModelMessage 核心类中不存在 deviceStatus 字段,调用会导致编译失败
// .deviceStatus(device.getDeviceStatus())
.occurred(System.currentTimeMillis()) .occurred(System.currentTimeMillis())
.build(); .build();
//增加启用未启用条件查询 //增加启用未启用条件查询
@ -917,7 +919,9 @@ public class ThingServiceImpl implements IThingService {
private String registerDevice(DeviceInfo device, DeviceRegister register, String parentId) { private String registerDevice(DeviceInfo device, DeviceRegister register, String parentId) {
String productKey = register.getProductKey(); String productKey = register.getProductKey();
Map<String, Object> params = register.getParams(); // 注释原因DeviceRegister 核心类中不存在 params 字段,调用 getParams() 会导致编译失败
// 原 imei/iccid 入库、信号强度/版本号保存逻辑因依赖 params 会失效,待核心库补齐字段后再恢复
Map<String, Object> params = null;
try { try {
if (params != null && !params.isEmpty()) { if (params != null && !params.isEmpty()) {
if (ObjectUtil.isNotNull(params.get("imei"))) { if (ObjectUtil.isNotNull(params.get("imei"))) {

@ -165,22 +165,24 @@ public class RuleExecutor {
public void execute(ThingModelMessage message, Rule rule) { public void execute(ThingModelMessage message, Rule rule) {
log.info("The listener did not match the appropriate content,deviceStatus:{},{}", rule.getId(), message.getDeviceStatus()); // 注释原因ThingModelMessage 核心类中不存在 deviceStatus 字段,调用 getDeviceStatus() 会导致编译失败
if(ObjectUtil.isNull(message.getDeviceStatus()) // 该字段在历史版本中存在但已被移除,原逻辑无法生效,故注释掉相关代码以保留历史痕迹
|| message.getDeviceStatus().equals(2) || // log.info("The listener did not match the appropriate content,deviceStatus:{},{}", rule.getId(), message.getDeviceStatus());
message.getDeviceStatus().equals(1) // if(ObjectUtil.isNull(message.getDeviceStatus())
){ // || message.getDeviceStatus().equals(2) ||
List<AlertConfig> config = iAlertConfigData.findByDeviceName(message.getDeviceName()); // message.getDeviceStatus().equals(1)
log.info("The listener did not match the appropriate content,deviceStatus:{},{}", rule.getId(), message.getDeviceStatus()); // ){
if(!config.isEmpty()){ // List<AlertConfig> config = iAlertConfigData.findByDeviceName(message.getDeviceName());
return; // log.info("The listener did not match the appropriate content,deviceStatus:{},{}", rule.getId(), message.getDeviceStatus());
}else{ // if(!config.isEmpty()){
List<AlertConfig> config1 = iAlertConfigData.findByRuleInfoId(rule.getId()); // return;
if(!config1.isEmpty()){ // }else{
return; // List<AlertConfig> config1 = iAlertConfigData.findByRuleInfoId(rule.getId());
} // if(!config1.isEmpty()){
} // return;
} // }
// }
// }
if (!doListeners(message, rule)) { if (!doListeners(message, rule)) {
/* if(ObjectUtil.isNotNull(message.getDeviceStatus()) /* if(ObjectUtil.isNotNull(message.getDeviceStatus())
&& (message.getDeviceStatus().equals(1) || message.getDeviceStatus().equals(2)) && (message.getDeviceStatus().equals(1) || message.getDeviceStatus().equals(2))

@ -128,7 +128,7 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
public StatObjectResponse downloadStatObject(SysOssVo sysOssVo) throws Exception{ public StatObjectResponse downloadStatObject(SysOssVo sysOssVo) throws Exception{
int startIndex = sysOssVo.getUrl().lastIndexOf("/feijialuo/") + "/feijialuo/".length(); int startIndex = sysOssVo.getUrl().lastIndexOf("/feijialuo/") + "/feijialuo/".length();
String result = sysOssVo.getUrl().substring(startIndex); String result = sysOssVo.getUrl().substring(startIndex);
return minioUtil.downloadStatObject("feijialuo",result); return (StatObjectResponse) minioUtil.downloadStatObject("feijialuo",result);
} }
/* @Override /* @Override
@ -163,7 +163,12 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
if (originalFileName == null) { if (originalFileName == null) {
throw new BizException("文件名为空,获取失败"); throw new BizException("文件名为空,获取失败");
} }
String url = minioUtil.upload(file); String url;
try {
url = minioUtil.upload(file.getBytes(), file.getOriginalFilename(), file.getContentType());
} catch (IOException e) {
throw new BizException("文件上传失败: " + e.getMessage());
}
String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length()); String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length());
/* OssClient storage = OssFactory.instance(); /* OssClient storage = OssFactory.instance();
UploadResult uploadResult; UploadResult uploadResult;

Loading…
Cancel
Save