You've already forked FrameTour-BE
feat(integration): 添加设备服务集成模块
- 新增设备服务配置和相关客户端接口 - 实现设备和设备配置的管理功能- 添加设备监控和状态管理示例 - 优化错误处理和故障恢复机制
This commit is contained in:
397
src/main/java/com/ycwl/basic/integration/CLAUDE.md
Normal file
397
src/main/java/com/ycwl/basic/integration/CLAUDE.md
Normal 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
|
Reference in New Issue
Block a user