원격 터미널 브리지 POC 전에 Client HTTP lifecycle과 Edge run result surface 계약을 고정해야 하므로 관련 구현, 테스트, 로드맵 상태를 함께 정리한다.
132 lines
4.3 KiB
Dart
132 lines
4.3 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;
|
|
final bool _ownsClient;
|
|
|
|
HttpControlPlaneStatusRepository({required this.baseUrl, http.Client? client})
|
|
: _client = client ?? http.Client(),
|
|
_ownsClient = client == null;
|
|
|
|
http.Client get _httpClient => _client;
|
|
|
|
void close() {
|
|
if (_ownsClient) {
|
|
_client.close();
|
|
}
|
|
}
|
|
|
|
@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);
|
|
}
|
|
}
|