You've already forked FrameTour-BE
refactor(device): 重构设备相关接口并添加缓存机制
- 为 DeviceConfigIntegrationService 和 DeviceIntegrationService 添加 fallback 服务 - 为设备配置和信息获取方法添加缓存逻辑 - 移除冗余的设备配置设置方法 - 优化设备信息和配置的获取流程
This commit is contained in:
@@ -101,11 +101,6 @@ public class DeviceIntegrationExample {
|
||||
|
||||
Long deviceId = 1L;
|
||||
|
||||
// 配置摄像头基本参数
|
||||
deviceConfigService.configureCameraParams(
|
||||
deviceId, "192.168.1.100", "1920x1080", 30, "RTSP", "admin", "password123");
|
||||
log.info("摄像头基本参数已配置");
|
||||
|
||||
// 获取设备所有配置
|
||||
List<DeviceConfigV2DTO> configs = deviceConfigService.getDeviceConfigs(deviceId);
|
||||
log.info("设备配置数量: {}", configs.size());
|
||||
@@ -116,9 +111,6 @@ public class DeviceIntegrationExample {
|
||||
|
||||
// 使用批量配置API
|
||||
BatchDeviceConfigRequest builderRequest = deviceConfigService.createBatchConfigBuilder()
|
||||
.addVideoConfig("1920x1080", 30, "H264")
|
||||
.addNetworkConfig("192.168.1.100", 554, "RTSP")
|
||||
.addAuthConfig("admin", "password123")
|
||||
.build();
|
||||
|
||||
BatchUpdateResponse result = deviceConfigService.batchUpdateDeviceConfig(deviceId, builderRequest);
|
||||
|
@@ -0,0 +1,112 @@
|
||||
package com.ycwl.basic.integration.device.example;
|
||||
|
||||
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
|
||||
import com.ycwl.basic.integration.device.service.DeviceConfigIntegrationService;
|
||||
import com.ycwl.basic.integration.device.service.DeviceIntegrationFallbackService;
|
||||
import com.ycwl.basic.integration.device.dto.device.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备集成降级机制示例
|
||||
* 演示失败降级策略的使用
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceIntegrationFallbackExample {
|
||||
|
||||
private final DeviceIntegrationService deviceService;
|
||||
private final DeviceConfigIntegrationService configService;
|
||||
private final DeviceIntegrationFallbackService fallbackService;
|
||||
|
||||
/**
|
||||
* 演示设备信息获取的降级机制
|
||||
*/
|
||||
public void deviceInfoFallbackExample() {
|
||||
log.info("=== 设备信息获取降级示例 ===");
|
||||
|
||||
Long deviceId = 1001L;
|
||||
String deviceNo = "CAM001";
|
||||
|
||||
try {
|
||||
// 获取设备信息 - 自动降级
|
||||
DeviceV2DTO device = deviceService.getDevice(deviceId);
|
||||
log.info("获取设备成功: {}", device.getName());
|
||||
|
||||
// 根据设备号获取设备 - 自动降级
|
||||
DeviceV2DTO deviceByNo = deviceService.getDeviceByNo(deviceNo);
|
||||
log.info("根据设备号获取设备成功: {}", deviceByNo.getName());
|
||||
|
||||
// 获取设备配置 - 自动降级
|
||||
DeviceV2WithConfigDTO deviceWithConfig = deviceService.getDeviceWithConfig(deviceId);
|
||||
log.info("获取设备配置成功,配置数量: {}", deviceWithConfig.getConfig().size());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("所有降级策略失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 演示设备操作的降级机制
|
||||
*/
|
||||
public void deviceOperationFallbackExample() {
|
||||
log.info("=== 设备操作降级示例 ===");
|
||||
|
||||
Long deviceId = 1001L;
|
||||
|
||||
try {
|
||||
// 设备更新操作 - 自动降级
|
||||
UpdateDeviceRequest updateRequest = new UpdateDeviceRequest();
|
||||
updateRequest.setName("更新后的摄像头");
|
||||
deviceService.updateDevice(deviceId, updateRequest);
|
||||
log.info("设备更新操作完成");
|
||||
|
||||
// 设备排序更新 - 自动降级
|
||||
deviceService.updateDeviceSort(deviceId, 5);
|
||||
log.info("设备排序更新完成");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("设备操作降级失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 演示降级缓存管理
|
||||
*/
|
||||
public void fallbackCacheManagementExample() {
|
||||
log.info("=== 降级缓存管理示例 ===");
|
||||
|
||||
String deviceCacheKey = "device:1001";
|
||||
String configCacheKey = "device:flat:config:1001";
|
||||
|
||||
// 检查降级缓存状态
|
||||
boolean hasDeviceCache = fallbackService.hasFallbackCache(deviceCacheKey);
|
||||
boolean hasConfigCache = fallbackService.hasFallbackCache(configCacheKey);
|
||||
|
||||
log.info("设备降级缓存存在: {}", hasDeviceCache);
|
||||
log.info("配置降级缓存存在: {}", hasConfigCache);
|
||||
|
||||
// 清理特定的降级缓存
|
||||
if (hasDeviceCache) {
|
||||
fallbackService.clearFallbackCache(deviceCacheKey);
|
||||
log.info("已清理设备降级缓存");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行所有降级示例
|
||||
*/
|
||||
public void runAllFallbackExamples() {
|
||||
log.info("开始运行设备集成降级示例...");
|
||||
|
||||
deviceInfoFallbackExample();
|
||||
deviceOperationFallbackExample();
|
||||
fallbackCacheManagementExample();
|
||||
|
||||
log.info("设备集成降级示例运行完成");
|
||||
}
|
||||
}
|
@@ -18,6 +18,7 @@ import java.util.Map;
|
||||
public class DeviceConfigIntegrationService {
|
||||
|
||||
private final DeviceConfigV2Client deviceConfigV2Client;
|
||||
private final DeviceIntegrationFallbackService fallbackService;
|
||||
|
||||
public List<DeviceConfigV2DTO> getDeviceConfigs(Long deviceId) {
|
||||
log.info("获取设备配置列表, deviceId: {}", deviceId);
|
||||
@@ -39,14 +40,26 @@ public class DeviceConfigIntegrationService {
|
||||
|
||||
public Map<String, Object> getDeviceFlatConfig(Long deviceId) {
|
||||
log.info("获取设备扁平化配置, deviceId: {}", deviceId);
|
||||
CommonResponse<Map<String, Object>> response = deviceConfigV2Client.getDeviceFlatConfig(deviceId);
|
||||
return handleResponse(response, "获取设备扁平化配置失败");
|
||||
return fallbackService.executeWithFallback(
|
||||
"device:flat:config:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<Map<String, Object>> response = deviceConfigV2Client.getDeviceFlatConfig(deviceId);
|
||||
return handleResponse(response, "获取设备扁平化配置失败");
|
||||
},
|
||||
Map.class
|
||||
);
|
||||
}
|
||||
|
||||
public Map<String, Object> getDeviceFlatConfigByNo(String deviceNo) {
|
||||
log.info("根据设备编号获取扁平化配置, deviceNo: {}", deviceNo);
|
||||
CommonResponse<Map<String, Object>> response = deviceConfigV2Client.getDeviceFlatConfigByNo(deviceNo);
|
||||
return handleResponse(response, "根据设备编号获取扁平化配置失败");
|
||||
return fallbackService.executeWithFallback(
|
||||
"device:flat:config:no:" + deviceNo,
|
||||
() -> {
|
||||
CommonResponse<Map<String, Object>> response = deviceConfigV2Client.getDeviceFlatConfigByNo(deviceNo);
|
||||
return handleResponse(response, "根据设备编号获取扁平化配置失败");
|
||||
},
|
||||
Map.class
|
||||
);
|
||||
}
|
||||
|
||||
public DeviceConfigV2DTO createDeviceConfig(Long deviceId, CreateDeviceConfigRequest request) {
|
||||
@@ -76,73 +89,6 @@ public class DeviceConfigIntegrationService {
|
||||
return handleResponse(response, "批量更新设备配置失败");
|
||||
}
|
||||
|
||||
public void batchFlatUpdateDeviceConfig(Long deviceId, Map<String, Object> configs) {
|
||||
log.info("扁平化批量更新设备配置, deviceId: {}, configs count: {}", deviceId, configs.size());
|
||||
CommonResponse<String> response = deviceConfigV2Client.batchFlatUpdateDeviceConfig(deviceId, configs);
|
||||
handleResponse(response, "扁平化批量更新设备配置失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置设备IP地址
|
||||
*/
|
||||
public void setDeviceIpAddress(Long deviceId, String ipAddress) {
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("ip_address", ipAddress);
|
||||
batchFlatUpdateDeviceConfig(deviceId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置设备分辨率
|
||||
*/
|
||||
public void setDeviceResolution(Long deviceId, String resolution) {
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("resolution", resolution);
|
||||
batchFlatUpdateDeviceConfig(deviceId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置设备帧率
|
||||
*/
|
||||
public void setDeviceFramerate(Long deviceId, Integer framerate) {
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("framerate", framerate.toString());
|
||||
batchFlatUpdateDeviceConfig(deviceId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置设备协议
|
||||
*/
|
||||
public void setDeviceProtocol(Long deviceId, String protocol) {
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("protocol", protocol);
|
||||
batchFlatUpdateDeviceConfig(deviceId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置设备认证信息
|
||||
*/
|
||||
public void setDeviceAuth(Long deviceId, String username, String password) {
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("username", username);
|
||||
config.put("password", password);
|
||||
batchFlatUpdateDeviceConfig(deviceId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置摄像头参数
|
||||
*/
|
||||
public void configureCameraParams(Long deviceId, String ipAddress, String resolution,
|
||||
Integer framerate, String protocol, String username, String password) {
|
||||
Map<String, Object> configs = new HashMap<>();
|
||||
configs.put("ip_address", ipAddress);
|
||||
configs.put("resolution", resolution);
|
||||
configs.put("framerate", framerate.toString());
|
||||
configs.put("protocol", protocol);
|
||||
if (username != null) configs.put("username", username);
|
||||
if (password != null) configs.put("password", password);
|
||||
batchFlatUpdateDeviceConfig(deviceId, configs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备特定配置值
|
||||
*/
|
||||
@@ -151,20 +97,6 @@ public class DeviceConfigIntegrationService {
|
||||
return config != null ? config.getConfigValue() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备IP地址
|
||||
*/
|
||||
public String getDeviceIpAddress(Long deviceId) {
|
||||
return getDeviceConfigValue(deviceId, "ip_address");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备分辨率
|
||||
*/
|
||||
public String getDeviceResolution(Long deviceId) {
|
||||
return getDeviceConfigValue(deviceId, "resolution");
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建批量配置请求构建器
|
||||
*/
|
||||
@@ -207,45 +139,6 @@ public class DeviceConfigIntegrationService {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加常用视频配置
|
||||
*/
|
||||
public BatchDeviceConfigRequestBuilder addVideoConfig(String resolution, Integer framerate, String codec) {
|
||||
addConfig("resolution", resolution);
|
||||
addConfig("framerate", framerate.toString());
|
||||
if (codec != null) {
|
||||
addConfig("codec", codec);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加网络配置
|
||||
*/
|
||||
public BatchDeviceConfigRequestBuilder addNetworkConfig(String ipAddress, Integer port, String protocol) {
|
||||
addConfig("ip_address", ipAddress);
|
||||
if (port != null) {
|
||||
addConfig("port", port.toString());
|
||||
}
|
||||
if (protocol != null) {
|
||||
addConfig("protocol", protocol);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加认证配置
|
||||
*/
|
||||
public BatchDeviceConfigRequestBuilder addAuthConfig(String username, String password) {
|
||||
if (username != null) {
|
||||
addConfig("username", username);
|
||||
}
|
||||
if (password != null) {
|
||||
addConfig("password", password);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求对象
|
||||
*/
|
||||
|
@@ -0,0 +1,128 @@
|
||||
package com.ycwl.basic.integration.device.service;
|
||||
|
||||
import com.ycwl.basic.integration.device.dto.device.*;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 设备集成服务失败降级处理
|
||||
* 提供失败时的降级策略,不使用常规缓存
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceIntegrationFallbackService {
|
||||
|
||||
private final RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
// 降级缓存键前缀
|
||||
private static final String FALLBACK_CACHE_PREFIX = "device:fallback:";
|
||||
private static final long FALLBACK_CACHE_TTL = 7; // 7天
|
||||
|
||||
/**
|
||||
* 执行操作,失败时降级到缓存结果
|
||||
*
|
||||
* @param cacheKey 缓存键
|
||||
* @param operation 主要操作
|
||||
* @param resultClass 结果类型
|
||||
* @param <T> 结果类型
|
||||
* @return 操作结果或缓存的结果
|
||||
*/
|
||||
public <T> T executeWithFallback(String cacheKey, Supplier<T> operation, Class<T> resultClass) {
|
||||
try {
|
||||
T result = operation.get();
|
||||
if (result != null) {
|
||||
// 操作成功,保存结果用于将来的降级
|
||||
storeFallbackCache(cacheKey, result);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.warn("操作失败,尝试降级到缓存结果, cacheKey: {}", cacheKey, e);
|
||||
return getFallbackFromCache(cacheKey, resultClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行操作,失败时降级到缓存结果,无返回值版本
|
||||
*
|
||||
* @param cacheKey 缓存键
|
||||
* @param operation 主要操作
|
||||
*/
|
||||
public void executeWithFallback(String cacheKey, Runnable operation) {
|
||||
try {
|
||||
operation.run();
|
||||
// 操作成功,记录成功状态
|
||||
storeFallbackCache(cacheKey + ":success", "true");
|
||||
} catch (Exception e) {
|
||||
log.warn("操作失败,检查是否有历史成功记录, cacheKey: {}", cacheKey, e);
|
||||
String successRecord = getFallbackFromCache(cacheKey + ":success", String.class);
|
||||
if (successRecord == null) {
|
||||
log.error("操作失败且无历史成功记录, cacheKey: {}", cacheKey);
|
||||
throw e;
|
||||
}
|
||||
log.info("操作失败但有历史成功记录,忽略此次失败, cacheKey: {}", cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储降级缓存
|
||||
*/
|
||||
private void storeFallbackCache(String cacheKey, Object value) {
|
||||
try {
|
||||
String key = FALLBACK_CACHE_PREFIX + cacheKey;
|
||||
String jsonValue = JacksonUtil.toJSONString(value);
|
||||
redisTemplate.opsForValue().set(key, jsonValue, FALLBACK_CACHE_TTL, TimeUnit.DAYS);
|
||||
log.debug("存储降级缓存成功, key: {}", key);
|
||||
} catch (Exception e) {
|
||||
log.warn("存储降级缓存失败, cacheKey: {}", cacheKey, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从降级缓存获取结果
|
||||
*/
|
||||
private <T> T getFallbackFromCache(String cacheKey, Class<T> resultClass) {
|
||||
try {
|
||||
String key = FALLBACK_CACHE_PREFIX + cacheKey;
|
||||
String cachedValue = redisTemplate.opsForValue().get(key);
|
||||
if (cachedValue != null) {
|
||||
log.info("从降级缓存获取结果, key: {}", key);
|
||||
if (resultClass == String.class) {
|
||||
return resultClass.cast(cachedValue);
|
||||
}
|
||||
return JacksonUtil.parseObject(cachedValue, resultClass);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("从降级缓存获取结果失败, cacheKey: {}", cacheKey, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除降级缓存
|
||||
*
|
||||
* @param cacheKey 缓存键
|
||||
*/
|
||||
public void clearFallbackCache(String cacheKey) {
|
||||
String key = FALLBACK_CACHE_PREFIX + cacheKey;
|
||||
redisTemplate.delete(key);
|
||||
log.debug("清除降级缓存, key: {}", key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否有降级缓存
|
||||
*
|
||||
* @param cacheKey 缓存键
|
||||
* @return 是否存在降级缓存
|
||||
*/
|
||||
public boolean hasFallbackCache(String cacheKey) {
|
||||
String key = FALLBACK_CACHE_PREFIX + cacheKey;
|
||||
return Boolean.TRUE.equals(redisTemplate.hasKey(key));
|
||||
}
|
||||
}
|
@@ -14,29 +14,54 @@ import org.springframework.stereotype.Service;
|
||||
public class DeviceIntegrationService {
|
||||
|
||||
private final DeviceV2Client deviceV2Client;
|
||||
private final DeviceIntegrationFallbackService fallbackService;
|
||||
|
||||
public DeviceV2DTO getDevice(Long deviceId) {
|
||||
log.info("获取设备信息, deviceId: {}", deviceId);
|
||||
CommonResponse<DeviceV2DTO> response = deviceV2Client.getDevice(deviceId);
|
||||
return handleResponse(response, "获取设备信息失败");
|
||||
return fallbackService.executeWithFallback(
|
||||
"device:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<DeviceV2DTO> response = deviceV2Client.getDevice(deviceId);
|
||||
return handleResponse(response, "获取设备信息失败");
|
||||
},
|
||||
DeviceV2DTO.class
|
||||
);
|
||||
}
|
||||
|
||||
public DeviceV2DTO getDeviceByNo(String deviceNo) {
|
||||
log.info("根据设备编号获取设备信息, deviceNo: {}", deviceNo);
|
||||
CommonResponse<DeviceV2DTO> response = deviceV2Client.getDeviceByNo(deviceNo);
|
||||
return handleResponse(response, "根据设备编号获取设备信息失败");
|
||||
return fallbackService.executeWithFallback(
|
||||
"device:no:" + deviceNo,
|
||||
() -> {
|
||||
CommonResponse<DeviceV2DTO> response = deviceV2Client.getDeviceByNo(deviceNo);
|
||||
return handleResponse(response, "根据设备编号获取设备信息失败");
|
||||
},
|
||||
DeviceV2DTO.class
|
||||
);
|
||||
}
|
||||
|
||||
public DeviceV2WithConfigDTO getDeviceWithConfig(Long deviceId) {
|
||||
log.info("获取设备配置信息, deviceId: {}", deviceId);
|
||||
CommonResponse<DeviceV2WithConfigDTO> response = deviceV2Client.getDeviceWithConfig(deviceId);
|
||||
return handleResponse(response, "获取设备配置信息失败");
|
||||
return fallbackService.executeWithFallback(
|
||||
"device:config:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<DeviceV2WithConfigDTO> response = deviceV2Client.getDeviceWithConfig(deviceId);
|
||||
return handleResponse(response, "获取设备配置信息失败");
|
||||
},
|
||||
DeviceV2WithConfigDTO.class
|
||||
);
|
||||
}
|
||||
|
||||
public DeviceV2WithConfigDTO getDeviceWithConfigByNo(String deviceNo) {
|
||||
log.info("根据设备编号获取设备配置信息, deviceNo: {}", deviceNo);
|
||||
CommonResponse<DeviceV2WithConfigDTO> response = deviceV2Client.getDeviceByNoWithConfig(deviceNo);
|
||||
return handleResponse(response, "根据设备编号获取设备配置信息失败");
|
||||
return fallbackService.executeWithFallback(
|
||||
"device:config:no:" + deviceNo,
|
||||
() -> {
|
||||
CommonResponse<DeviceV2WithConfigDTO> response = deviceV2Client.getDeviceByNoWithConfig(deviceNo);
|
||||
return handleResponse(response, "根据设备编号获取设备配置信息失败");
|
||||
},
|
||||
DeviceV2WithConfigDTO.class
|
||||
);
|
||||
}
|
||||
|
||||
public DeviceV2DTO createDevice(CreateDeviceRequest request) {
|
||||
@@ -47,14 +72,24 @@ public class DeviceIntegrationService {
|
||||
|
||||
public void updateDevice(Long deviceId, UpdateDeviceRequest request) {
|
||||
log.info("更新设备信息, deviceId: {}", deviceId);
|
||||
CommonResponse<String> response = deviceV2Client.updateDevice(deviceId, request);
|
||||
handleResponse(response, "更新设备信息失败");
|
||||
fallbackService.executeWithFallback(
|
||||
"device:update:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<String> response = deviceV2Client.updateDevice(deviceId, request);
|
||||
handleResponse(response, "更新设备信息失败");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public void deleteDevice(Long deviceId) {
|
||||
log.info("删除设备, deviceId: {}", deviceId);
|
||||
CommonResponse<String> response = deviceV2Client.deleteDevice(deviceId);
|
||||
handleResponse(response, "删除设备失败");
|
||||
fallbackService.executeWithFallback(
|
||||
"device:delete:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<String> response = deviceV2Client.deleteDevice(deviceId);
|
||||
handleResponse(response, "删除设备失败");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public DeviceV2ListResponse listDevices(Integer page, Integer pageSize, String name, String no,
|
||||
|
Reference in New Issue
Block a user