iop/apps/client/lib/control_plane_status_repository.dart
toki 9024c852df refactor: architecture refactor - fleet polling & client state split
- Move fleet polling logic to control orchestrator
- Split client state management into separate controller/repository
- Add client bootstrap and home page components
- Update HTTP fleet handlers and views
- Add unit tests for client bootstrap and status controller
- Archive completed subtask documents
2026-06-06 19:10:47 +09:00

107 lines
4 KiB
Dart

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'control_plane_status_dto.dart';
abstract class ControlPlaneStatusRepository {
Future<List<EdgeRegistryView>> fetchEdges();
Future<EdgeStatusResponseView> fetchEdgeStatus(String edgeId);
Future<List<EdgeNodeEventView>> fetchEdgeEvents(String edgeId);
Future<FleetStatusResponseView> fetchFleetStatus();
Future<EdgeOperationsResponseView> fetchEdgeOperations(String edgeId);
Future<EdgeCommandResponseView> sendEdgeCommand(
String edgeId,
String operation, {
String? targetSelector,
Map<String, String>? parameters,
});
}
class HttpControlPlaneStatusRepository implements ControlPlaneStatusRepository {
final String baseUrl;
final http.Client? client;
HttpControlPlaneStatusRepository({required this.baseUrl, this.client});
http.Client get _httpClient => client ?? http.Client();
@override
Future<List<EdgeRegistryView>> fetchEdges() async {
final response = await _httpClient.get(Uri.parse('$baseUrl/edges'));
if (response.statusCode != 200) {
throw Exception('Failed to fetch edges: ${response.statusCode}');
}
final body = json.decode(response.body) as Map<String, dynamic>;
final list = body['edges'] as List? ?? [];
return list.map((e) => EdgeRegistryView.fromJson(e as Map<String, dynamic>)).toList();
}
@override
Future<EdgeStatusResponseView> fetchEdgeStatus(String edgeId) async {
final response = await _httpClient.get(Uri.parse('$baseUrl/edges/$edgeId/status'));
if (response.statusCode != 200) {
throw Exception('Failed to fetch status for $edgeId: ${response.statusCode}');
}
final body = json.decode(response.body) as Map<String, dynamic>;
return EdgeStatusResponseView.fromJson(body);
}
@override
Future<List<EdgeNodeEventView>> fetchEdgeEvents(String edgeId) async {
final response = await _httpClient.get(Uri.parse('$baseUrl/edges/$edgeId/events'));
if (response.statusCode != 200) {
throw Exception('Failed to fetch events for $edgeId: ${response.statusCode}');
}
final body = json.decode(response.body) as Map<String, dynamic>;
final list = body['events'] as List? ?? [];
return list.map((e) => EdgeNodeEventView.fromJson(e as Map<String, dynamic>)).toList();
}
@override
Future<FleetStatusResponseView> fetchFleetStatus() async {
final response = await _httpClient.get(Uri.parse('$baseUrl/fleet/status'));
if (response.statusCode != 200) {
throw Exception('Failed to fetch fleet status: ${response.statusCode}');
}
final body = json.decode(response.body) as Map<String, dynamic>;
return FleetStatusResponseView.fromJson(body);
}
@override
Future<EdgeOperationsResponseView> fetchEdgeOperations(String edgeId) async {
final response = await _httpClient.get(Uri.parse('$baseUrl/edges/$edgeId/operations'));
if (response.statusCode != 200) {
throw Exception('Failed to fetch operations for $edgeId: ${response.statusCode}');
}
final body = json.decode(response.body) as Map<String, dynamic>;
return EdgeOperationsResponseView.fromJson(body);
}
@override
Future<EdgeCommandResponseView> sendEdgeCommand(
String edgeId,
String operation, {
String? targetSelector,
Map<String, String>? parameters,
}) async {
final Map<String, dynamic> requestBody = {
'operation': operation,
};
if (targetSelector != null) {
requestBody['target_selector'] = targetSelector;
}
if (parameters != null) {
requestBody['parameters'] = parameters;
}
final response = await _httpClient.post(
Uri.parse('$baseUrl/edges/$edgeId/commands'),
headers: {'Content-Type': 'application/json'},
body: json.encode(requestBody),
);
if (response.statusCode != 200 && response.statusCode != 202) {
throw Exception('Failed to send command to $edgeId: ${response.statusCode}');
}
final body = json.decode(response.body) as Map<String, dynamic>;
return EdgeCommandResponseView.fromJson(body);
}
}