feat(integration): 添加设备服务集成模块

- 新增设备服务配置和相关客户端接口
- 实现设备和设备配置的管理功能- 添加设备监控和状态管理示例
- 优化错误处理和故障恢复机制
This commit is contained in:
2025-08-30 23:24:49 +08:00
parent a9d64402f2
commit d34603062a
19 changed files with 1484 additions and 1 deletions

View File

@@ -0,0 +1,397 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Integration Package Overview
The integration package (`com.ycwl.basic.integration`) is responsible for external microservice integrations using Spring Cloud OpenFeign and Nacos service discovery. It provides a standardized approach for calling external services with proper error handling, configuration management, and response processing.
## Architecture
### Core Components
#### Common Infrastructure (`com.ycwl.basic.integration.common`)
- **IntegrationProperties**: Centralized configuration properties for all integrations
- **FeignConfig**: Global Feign configuration with error decoder and request interceptors
- **FeignErrorDecoder**: Custom error decoder that converts Feign errors to IntegrationException
- **IntegrationException**: Standardized exception for integration failures
- **CommonResponse/PageResponse**: Standard response wrappers for external service calls
- **ConfigValueUtil**: Utility for handling configuration values
#### Service-Specific Integrations
Currently implemented:
- **Scenic Integration** (`com.ycwl.basic.integration.scenic`): ZT-Scenic microservice integration
- **Device Integration** (`com.ycwl.basic.integration.device`): ZT-Device microservice integration
### Integration Pattern
Each external service integration follows this structure:
```
service/
├── client/ # Feign clients for HTTP calls
├── config/ # Service-specific configuration
├── dto/ # Data transfer objects
├── service/ # Service layer with business logic
└── example/ # Usage examples
```
## Scenic Integration (ZT-Scenic Microservice)
### Key Components
#### Feign Clients
- **ScenicV2Client**: Main scenic operations (CRUD, filtering, listing)
- **ScenicConfigV2Client**: Scenic configuration management
- **DefaultConfigClient**: Default configuration operations
#### Services
- **ScenicIntegrationService**: High-level scenic operations
- **ScenicConfigIntegrationService**: Configuration management
- **DefaultConfigIntegrationService**: Default configuration handling
#### Configuration
```yaml
integration:
scenic:
enabled: true
serviceName: zt-scenic
connectTimeout: 5000
readTimeout: 10000
retryEnabled: false
maxRetries: 3
```
### Usage Examples
#### Basic Scenic Operations
```java
@Autowired
private ScenicIntegrationService scenicService;
// Get scenic with configuration
ScenicV2WithConfigDTO scenic = scenicService.getScenicWithConfig(scenicId);
// Create new scenic
CreateScenicRequest request = new CreateScenicRequest();
request.setName("Test Scenic");
ScenicV2DTO result = scenicService.createScenic(request);
// Filter scenics
ScenicFilterRequest filterRequest = new ScenicFilterRequest();
// configure filters...
ScenicFilterPageResponse response = scenicService.filterScenics(filterRequest);
```
#### Configuration Management
```java
@Autowired
private ScenicConfigIntegrationService configService;
// Get flat configuration
Map<String, Object> config = scenicService.getScenicFlatConfig(scenicId);
// Batch update configurations
BatchConfigRequest batchRequest = new BatchConfigRequest();
// configure batch updates...
configService.batchUpdateConfigs(scenicId, batchRequest);
```
## Device Integration (ZT-Device Microservice)
### Key Components
#### Feign Clients
- **DeviceV2Client**: Main device operations (CRUD, filtering, listing)
- **DeviceConfigV2Client**: Device configuration management
#### Services
- **DeviceIntegrationService**: High-level device operations
- **DeviceConfigIntegrationService**: Device configuration management
#### Configuration
```yaml
integration:
device:
enabled: true
serviceName: zt-device
connectTimeout: 5000
readTimeout: 10000
retryEnabled: false
maxRetries: 3
```
### Usage Examples
#### Basic Device Operations
```java
@Autowired
private DeviceIntegrationService deviceService;
// Create IPC camera device
DeviceV2DTO ipcDevice = deviceService.createIpcDevice("前门摄像头", "CAM001", scenicId);
// Get device with configuration
DeviceV2WithConfigDTO device = deviceService.getDeviceWithConfig(deviceId);
// Get device by number
DeviceV2DTO deviceByNo = deviceService.getDeviceByNo("CAM001");
// List scenic devices
DeviceV2ListResponse deviceList = deviceService.getScenicIpcDevices(scenicId, 1, 10);
// Enable/disable device
deviceService.enableDevice(deviceId);
deviceService.disableDevice(deviceId);
```
#### Device Configuration Management
```java
@Autowired
private DeviceConfigIntegrationService configService;
// Configure camera basic parameters
configService.configureCameraBasicParams(deviceId, "192.168.1.100", "1920x1080", 30, "RTSP");
// Configure camera with authentication
configService.configureCameraFullParams(deviceId, "192.168.1.100", "1920x1080", 30, "RTSP", "admin", "password");
// Set specific configuration
configService.setDeviceIpAddress(deviceId, "192.168.1.101");
configService.setDeviceResolution(deviceId, "2560x1440");
configService.setDeviceFramerate(deviceId, 60);
// Get flat configuration
Map<String, Object> config = configService.getDeviceFlatConfig(deviceId);
// Batch update configurations
Map<String, Object> batchConfigs = new HashMap<>();
batchConfigs.put("brightness", "50");
batchConfigs.put("contrast", "80");
configService.batchFlatUpdateDeviceConfig(deviceId, batchConfigs);
```
#### Device Management Patterns
```java
// Create and configure camera in one operation
DeviceV2DTO camera = deviceService.createIpcDevice("摄像头1", "CAM001", scenicId);
configService.configureCameraFullParams(camera.getId(), "192.168.1.100", "1920x1080", 30, "RTSP", "admin", "password");
// Get scenic camera status
DeviceV2WithConfigListResponse camerasWithConfig =
deviceService.listDevicesWithConfig(1, 100, null, null, "IPC", 1, scenicId);
// Batch update camera resolution
for (DeviceV2WithConfigDTO device : camerasWithConfig.getList()) {
configService.setDeviceResolution(device.getId(), "2560x1440");
}
// Monitor device configuration completeness
for (DeviceV2DTO device : activeDevices.getList()) {
Map<String, Object> config = configService.getDeviceFlatConfig(device.getId());
boolean hasIpConfig = config.containsKey("ip_address");
// log configuration status...
}
```
### Device Types
- **IPC**: IP Camera devices for video monitoring
- **CUSTOM**: Custom device types for sensors, controllers, etc.
### Common Configuration Keys
- `ip_address`: Device IP address
- `resolution`: Video resolution (e.g., "1920x1080", "3840x2160")
- `framerate`: Video frame rate (integer)
- `protocol`: Communication protocol (e.g., "RTSP", "HTTP")
- `username`: Authentication username
- `password`: Authentication password
- `brightness`: Display brightness (0-100)
- `contrast`: Display contrast (0-100)
- `quality`: Video quality ("low", "medium", "high")
## Adding New Service Integrations
### 1. Create Package Structure
```
com.ycwl.basic.integration.{service-name}/
├── client/
├── config/
├── dto/
├── service/
└── example/
```
### 2. Add Configuration Properties
Update `IntegrationProperties` to include new service configuration:
```java
@Data
public static class NewServiceConfig {
private boolean enabled = true;
private String serviceName = "service-name";
private int connectTimeout = 5000;
private int readTimeout = 10000;
// other configs...
}
```
### 3. Create Feign Client
```java
@FeignClient(name = "service-name", contextId = "service-context", path = "/api/path")
public interface NewServiceClient {
@GetMapping("/endpoint")
CommonResponse<ResponseDTO> getData(@PathVariable Long id);
// other endpoints...
}
```
### 4. Implement Service Layer
```java
@Service
@RequiredArgsConstructor
public class NewServiceIntegrationService {
private final NewServiceClient client;
public ResponseDTO getData(Long id) {
CommonResponse<ResponseDTO> response = client.getData(id);
return handleResponse(response, "Failed to get data");
}
private <T> T handleResponse(CommonResponse<T> response, String errorMessage) {
if (response == null || !response.isSuccess()) {
String msg = response != null && response.getMessage() != null
? response.getMessage()
: errorMessage;
Integer code = response != null ? response.getCode() : 5000;
throw new IntegrationException(code, msg, "service-name");
}
return response.getData();
}
}
```
## Error Handling
### IntegrationException
All integration failures are wrapped in `IntegrationException`:
```java
public class IntegrationException extends RuntimeException {
private final Integer code;
private final String serviceName;
// constructors and getters...
}
```
### FeignErrorDecoder
Automatically converts Feign errors to IntegrationException:
- Parses CommonResponse error format
- Extracts service name from method key
- Provides meaningful error messages
## Configuration Management
### Properties Structure
```yaml
integration:
scenic:
enabled: true
serviceName: zt-scenic
connectTimeout: 5000
readTimeout: 10000
retryEnabled: false
maxRetries: 3
device:
enabled: true
serviceName: zt-device
connectTimeout: 5000
readTimeout: 10000
retryEnabled: false
maxRetries: 3
```
### Configuration Refresh
Uses `@RefreshScope` to support dynamic configuration updates without restart.
## Testing Integration Services
### Unit Testing
Test service layers by mocking Feign clients:
```java
@ExtendWith(MockitoExtension.class)
class ScenicIntegrationServiceTest {
@Mock
private ScenicV2Client scenicV2Client;
@InjectMocks
private ScenicIntegrationService scenicService;
@Test
void testGetScenic() {
// Mock response
CommonResponse<ScenicV2DTO> response = new CommonResponse<>();
response.setSuccess(true);
response.setData(new ScenicV2DTO());
when(scenicV2Client.getScenic(1L)).thenReturn(response);
// Test
ScenicV2DTO result = scenicService.getScenic(1L);
assertNotNull(result);
}
}
```
### Integration Testing
Use `@SpringBootTest` with test profiles and mock external services.
## Common Development Tasks
### Running Integration Tests
```bash
# Run specific integration test class
mvn test -Dtest=ScenicIntegrationServiceTest
# Run all integration tests
mvn test -Dtest="com.ycwl.basic.integration.*Test"
# Run device integration tests
mvn test -Dtest=DeviceIntegrationServiceTest
mvn test -Dtest="com.ycwl.basic.integration.device.*Test"
```
### Adding New DTOs
1. Create DTO classes in the appropriate `dto` package
2. Follow existing patterns with proper Jackson annotations
3. Use `@JsonProperty` for field mapping when needed
### Debugging Integration Issues
1. Enable Feign client logging in `application-dev.yml`:
```yaml
logging:
level:
com.ycwl.basic.integration: DEBUG
```
2. Check Nacos service discovery in development
3. Verify service configurations and timeouts
4. Review FeignErrorDecoder logs for detailed error information
## Best Practices
### Response Handling
- Always use the `handleResponse` pattern for consistent error handling
- Provide meaningful error messages for business context
- Include service name in IntegrationException for debugging
### Configuration
- Use environment-specific configuration profiles
- Set appropriate timeouts based on service characteristics
- Enable retries only when safe (idempotent operations)
### DTOs and Mapping
- Keep DTOs simple and focused on data transfer
- Use proper Jackson annotations for field mapping
- Separate request/response DTOs for clarity
### Service Layer Design
- Keep integration services focused on external service calls
- Handle response transformation and error conversion
- Avoid business logic in integration services