EG/plugins/user/server_architecture/api/api_interface.py
2025-12-12 16:16:15 +08:00

880 lines
32 KiB
Python

"""
API接口模块
提供RESTful API供外部系统调用
"""
import time
import threading
import json
from typing import Dict, Any, List, Optional
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
class APIInterface:
"""
API接口
提供RESTful API供外部系统调用
"""
def __init__(self, plugin):
"""
初始化API接口
Args:
plugin: 服务器架构插件实例
"""
self.plugin = plugin
self.enabled = False
self.initialized = False
# API配置
self.api_config = {
"enable_api": True,
"api_host": "0.0.0.0",
"api_port": 8081,
"enable_cors": True,
"allowed_origins": ["*"],
"enable_authentication": True,
"api_version": "v1",
"max_request_size": 1048576, # 1MB
"enable_rate_limiting": True,
"requests_per_minute": 60,
"enable_logging": True,
"enable_swagger": True
}
# API路由
self.routes = {
"GET": {},
"POST": {},
"PUT": {},
"DELETE": {}
}
# API状态
self.api_state = {
"is_running": False,
"start_time": 0.0,
"uptime": 0.0,
"total_requests": 0,
"successful_requests": 0,
"failed_requests": 0,
"active_connections": 0
}
# API统计
self.api_stats = {
"requests_handled": 0,
"bytes_sent": 0,
"bytes_received": 0,
"average_response_time": 0.0,
"errors": 0
}
# HTTP服务器
self.http_server = None
self.server_thread = None
# 回调函数
self.api_callbacks = {
"api_started": [],
"api_stopped": [],
"request_received": [],
"request_processed": [],
"api_error": []
}
# 时间戳记录
self.last_request_time = 0.0
self.last_stats_update = 0.0
print("✓ API接口已创建")
def initialize(self) -> bool:
"""
初始化API接口
Returns:
是否初始化成功
"""
try:
print("正在初始化API接口...")
# 注册默认路由
self._register_default_routes()
self.initialized = True
print("✓ API接口初始化完成")
return True
except Exception as e:
print(f"✗ API接口初始化失败: {e}")
self.api_stats["errors"] += 1
import traceback
traceback.print_exc()
return False
def _register_default_routes(self):
"""注册默认路由"""
try:
# 系统信息路由
self.register_route("GET", "/api/v1/system/info", self._handle_system_info)
self.register_route("GET", "/api/v1/system/stats", self._handle_system_stats)
self.register_route("GET", "/api/v1/system/config", self._handle_system_config)
# 客户端管理路由
self.register_route("GET", "/api/v1/clients", self._handle_get_clients)
self.register_route("GET", "/api/v1/clients/{client_id}", self._handle_get_client)
self.register_route("DELETE", "/api/v1/clients/{client_id}", self._handle_kick_client)
# 房间管理路由
self.register_route("GET", "/api/v1/rooms", self._handle_get_rooms)
self.register_route("POST", "/api/v1/rooms", self._handle_create_room)
self.register_route("GET", "/api/v1/rooms/{room_id}", self._handle_get_room)
self.register_route("DELETE", "/api/v1/rooms/{room_id}", self._handle_destroy_room)
# 监控路由
self.register_route("GET", "/api/v1/monitoring/metrics", self._handle_get_metrics)
self.register_route("GET", "/api/v1/monitoring/alerts", self._handle_get_alerts)
# Swagger UI路由
if self.api_config["enable_swagger"]:
self.register_route("GET", "/api/swagger", self._handle_swagger_ui)
self.register_route("GET", "/api/swagger.json", self._handle_swagger_spec)
print("✓ 默认API路由已注册")
except Exception as e:
print(f"✗ 默认API路由注册失败: {e}")
self.api_stats["errors"] += 1
def enable(self) -> bool:
"""
启用API接口
Returns:
是否启用成功
"""
try:
if not self.initialized:
print("✗ API接口未初始化")
return False
# 启动HTTP服务器
self._start_http_server()
self.enabled = True
print("✓ API接口已启用")
return True
except Exception as e:
print(f"✗ API接口启用失败: {e}")
self.api_stats["errors"] += 1
import traceback
traceback.print_exc()
return False
def disable(self):
"""禁用API接口"""
try:
self.enabled = False
# 停止HTTP服务器
self._stop_http_server()
print("✓ API接口已禁用")
except Exception as e:
print(f"✗ API接口禁用失败: {e}")
self.api_stats["errors"] += 1
import traceback
traceback.print_exc()
def finalize(self):
"""清理API接口资源"""
try:
# 禁用API接口
if self.enabled:
self.disable()
# 清理回调
self.api_callbacks.clear()
self.routes.clear()
self.initialized = False
print("✓ API接口资源已清理")
except Exception as e:
print(f"✗ API接口资源清理失败: {e}")
import traceback
traceback.print_exc()
def update(self, dt: float):
"""
更新API接口状态
Args:
dt: 时间增量(秒)
"""
try:
if not self.enabled:
return
current_time = time.time()
self.last_request_time = current_time
# 更新运行时间
if self.api_state["is_running"]:
self.api_state["uptime"] = current_time - self.api_state["start_time"]
except Exception as e:
print(f"✗ API接口更新失败: {e}")
self.api_stats["errors"] += 1
import traceback
traceback.print_exc()
def _start_http_server(self):
"""启动HTTP服务器"""
try:
if self.api_state["is_running"]:
return
# 创建HTTP请求处理器
api_interface = self
class APIRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
api_interface._handle_request(self, "GET")
def do_POST(self):
api_interface._handle_request(self, "POST")
def do_PUT(self):
api_interface._handle_request(self, "PUT")
def do_DELETE(self):
api_interface._handle_request(self, "DELETE")
def log_message(self, format, *args):
if api_interface.api_config["enable_logging"]:
print(f"[API] {format % args}")
# 启动HTTP服务器
host = self.api_config["api_host"]
port = self.api_config["api_port"]
self.http_server = HTTPServer((host, port), APIRequestHandler)
self.server_thread = threading.Thread(target=self.http_server.serve_forever, daemon=True)
self.server_thread.start()
self.api_state["is_running"] = True
self.api_state["start_time"] = time.time()
# 触发API启动回调
self._trigger_api_callback("api_started", {
"host": host,
"port": port,
"timestamp": self.api_state["start_time"]
})
print(f"✓ API服务器已启动: http://{host}:{port}")
except Exception as e:
print(f"✗ HTTP服务器启动失败: {e}")
self.api_stats["errors"] += 1
def _stop_http_server(self):
"""停止HTTP服务器"""
try:
if not self.api_state["is_running"]:
return
if self.http_server:
self.http_server.shutdown()
self.http_server.server_close()
self.http_server = None
if self.server_thread and self.server_thread.is_alive():
self.server_thread.join(timeout=5.0)
self.server_thread = None
self.api_state["is_running"] = False
self.api_state["start_time"] = 0.0
self.api_state["uptime"] = 0.0
# 触发API停止回调
self._trigger_api_callback("api_stopped", {
"timestamp": time.time()
})
print("✓ API服务器已停止")
except Exception as e:
print(f"✗ HTTP服务器停止失败: {e}")
self.api_stats["errors"] += 1
def _handle_request(self, handler: BaseHTTPRequestHandler, method: str):
"""
处理HTTP请求
Args:
handler: HTTP请求处理器
method: HTTP方法
"""
try:
start_time = time.time()
# 解析请求
parsed_url = urlparse(handler.path)
path = parsed_url.path
query_params = parse_qs(parsed_url.query)
# 读取请求体
content_length = int(handler.headers.get('Content-Length', 0))
if content_length > self.api_config["max_request_size"]:
self._send_error_response(handler, 413, "Request Entity Too Large")
return
request_body = handler.rfile.read(content_length) if content_length > 0 else b""
# 解析JSON请求体
request_data = {}
if request_body:
try:
request_data = json.loads(request_body.decode('utf-8'))
except json.JSONDecodeError:
self._send_error_response(handler, 400, "Invalid JSON")
return
# 记录请求
self.api_state["total_requests"] += 1
# 触发请求接收回调
self._trigger_api_callback("request_received", {
"method": method,
"path": path,
"client_address": handler.client_address,
"timestamp": start_time
})
# 查找路由处理器
route_handler = self._find_route_handler(method, path)
if not route_handler:
self._send_error_response(handler, 404, "Not Found")
self.api_state["failed_requests"] += 1
return
# 处理请求
try:
response_data = route_handler({
"method": method,
"path": path,
"query_params": query_params,
"body": request_data,
"headers": dict(handler.headers),
"client_address": handler.client_address
})
# 发送响应
self._send_json_response(handler, 200, response_data)
self.api_state["successful_requests"] += 1
except Exception as e:
print(f"✗ API路由处理失败: {e}")
self._send_error_response(handler, 500, f"Internal Server Error: {str(e)}")
self.api_state["failed_requests"] += 1
self.api_stats["errors"] += 1
return
# 更新统计
end_time = time.time()
response_time = end_time - start_time
self.api_stats["requests_handled"] += 1
self.api_stats["average_response_time"] = (
(self.api_stats["average_response_time"] * (self.api_stats["requests_handled"] - 1) + response_time)
/ self.api_stats["requests_handled"]
)
# 触发请求处理回调
self._trigger_api_callback("request_processed", {
"method": method,
"path": path,
"response_time": response_time,
"timestamp": end_time
})
except Exception as e:
print(f"✗ HTTP请求处理失败: {e}")
self.api_stats["errors"] += 1
try:
self._send_error_response(handler, 500, f"Internal Server Error: {str(e)}")
except:
pass
def _find_route_handler(self, method: str, path: str):
"""
查找路由处理器
Args:
method: HTTP方法
path: 请求路径
Returns:
路由处理器函数或None
"""
try:
if method not in self.routes:
return None
# 精确匹配
if path in self.routes[method]:
return self.routes[method][path]
# 参数化路径匹配
for route_path, handler in self.routes[method].items():
if "{" in route_path and "}" in route_path:
# 简单的参数化路径匹配
route_parts = route_path.split("/")
path_parts = path.split("/")
if len(route_parts) == len(path_parts):
match = True
for i in range(len(route_parts)):
if route_parts[i] != path_parts[i] and not (route_parts[i].startswith("{") and route_parts[i].endswith("}")):
match = False
break
if match:
return handler
return None
except Exception as e:
print(f"✗ 路由查找失败: {e}")
self.api_stats["errors"] += 1
return None
def register_route(self, method: str, path: str, handler: callable):
"""
注册API路由
Args:
method: HTTP方法 (GET, POST, PUT, DELETE)
path: 路径
handler: 处理器函数
"""
try:
if method not in self.routes:
self.routes[method] = {}
self.routes[method][path] = handler
print(f"✓ API路由已注册: {method} {path}")
except Exception as e:
print(f"✗ API路由注册失败: {e}")
self.api_stats["errors"] += 1
def _send_json_response(self, handler: BaseHTTPRequestHandler, status_code: int, data: Any):
"""
发送JSON响应
Args:
handler: HTTP请求处理器
status_code: 状态码
data: 响应数据
"""
try:
response_data = json.dumps(data, ensure_ascii=False)
response_bytes = response_data.encode('utf-8')
handler.send_response(status_code)
handler.send_header('Content-Type', 'application/json; charset=utf-8')
handler.send_header('Content-Length', str(len(response_bytes)))
# CORS头
if self.api_config["enable_cors"]:
handler.send_header('Access-Control-Allow-Origin', '*')
handler.send_header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
handler.send_header('Access-Control-Allow-Headers', '*')
handler.end_headers()
handler.wfile.write(response_bytes)
self.api_stats["bytes_sent"] += len(response_bytes)
except Exception as e:
print(f"✗ JSON响应发送失败: {e}")
self.api_stats["errors"] += 1
def _send_error_response(self, handler: BaseHTTPRequestHandler, status_code: int, message: str):
"""
发送错误响应
Args:
handler: HTTP请求处理器
status_code: 状态码
message: 错误消息
"""
try:
error_data = {
"error": message,
"status_code": status_code,
"timestamp": time.time()
}
self._send_json_response(handler, status_code, error_data)
except Exception as e:
print(f"✗ 错误响应发送失败: {e}")
self.api_stats["errors"] += 1
# 默认路由处理器
def _handle_system_info(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理系统信息请求"""
return {
"name": "EG Server Architecture",
"version": "1.0.0",
"status": "running",
"uptime": self.api_state["uptime"],
"timestamp": time.time()
}
def _handle_system_stats(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理系统统计请求"""
# 收集各模块统计信息
stats = {
"server": self.plugin.server_manager.get_server_stats() if self.plugin.server_manager else {},
"clients": self.plugin.client_manager.get_client_stats() if self.plugin.client_manager else {},
"rooms": self.plugin.room_manager.get_room_stats() if self.plugin.room_manager else {},
"messages": self.plugin.message_router.get_message_stats() if self.plugin.message_router else {},
"storage": self.plugin.storage_manager.get_storage_stats() if self.plugin.storage_manager else {},
"loadbalancer": self.plugin.load_balancer.get_loadbalancer_stats() if self.plugin.load_balancer else {},
"monitoring": self.plugin.monitoring_system.get_monitoring_stats() if self.plugin.monitoring_system else {},
"security": self.plugin.security_manager.get_security_stats() if self.plugin.security_manager else {},
"api": self.api_state.copy()
}
return {
"stats": stats,
"timestamp": time.time()
}
def _handle_system_config(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理系统配置请求"""
config = {
"server": self.plugin.config_manager.get_config("server") if self.plugin.config_manager else {},
"client": self.plugin.config_manager.get_config("client") if self.plugin.config_manager else {},
"room": self.plugin.config_manager.get_config("room") if self.plugin.config_manager else {},
"storage": self.plugin.config_manager.get_config("storage") if self.plugin.config_manager else {},
"loadbalancer": self.plugin.config_manager.get_config("loadbalancer") if self.plugin.config_manager else {},
"monitoring": self.plugin.config_manager.get_config("monitoring") if self.plugin.config_manager else {},
"security": self.plugin.config_manager.get_config("security") if self.plugin.config_manager else {},
"api": self.api_config.copy()
}
return {
"config": config,
"timestamp": time.time()
}
def _handle_get_clients(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理获取客户端列表请求"""
clients = self.plugin.client_manager.get_all_clients() if self.plugin.client_manager else {}
return {
"clients": clients,
"count": len(clients),
"timestamp": time.time()
}
def _handle_get_client(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理获取客户端信息请求"""
path_parts = request["path"].split("/")
client_id = path_parts[-1] if len(path_parts) > 0 else None
if not client_id:
return {"error": "Missing client_id"}
client_info = self.plugin.client_manager.get_client(client_id) if self.plugin.client_manager else None
if not client_info:
return {"error": "Client not found"}
return {
"client": client_info,
"timestamp": time.time()
}
def _handle_kick_client(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理踢出客户端请求"""
path_parts = request["path"].split("/")
client_id = path_parts[-1] if len(path_parts) > 0 else None
if not client_id:
return {"error": "Missing client_id"}
if self.plugin.client_manager:
self.plugin.client_manager.disconnect_client(client_id, "kicked_by_admin")
return {
"message": f"Client {client_id} kicked successfully",
"timestamp": time.time()
}
else:
return {"error": "Client manager not available"}
def _handle_get_rooms(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理获取房间列表请求"""
rooms = self.plugin.room_manager.get_all_rooms() if self.plugin.room_manager else []
return {
"rooms": rooms,
"count": len(rooms),
"timestamp": time.time()
}
def _handle_create_room(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理创建房间请求"""
room_data = request.get("body", {})
room_name = room_data.get("room_name")
room_settings = room_data.get("settings", {})
room_password = room_data.get("password")
if self.plugin.room_manager:
room_id = self.plugin.room_manager.create_room(room_name, room_settings, room_password)
if room_id:
return {
"message": "Room created successfully",
"room_id": room_id,
"timestamp": time.time()
}
else:
return {"error": "Failed to create room"}
else:
return {"error": "Room manager not available"}
def _handle_get_room(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理获取房间信息请求"""
path_parts = request["path"].split("/")
room_id = path_parts[-1] if len(path_parts) > 0 else None
if not room_id:
return {"error": "Missing room_id"}
room_info = self.plugin.room_manager.get_room_info(room_id) if self.plugin.room_manager else None
if not room_info:
return {"error": "Room not found"}
return {
"room": room_info,
"timestamp": time.time()
}
def _handle_destroy_room(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理销毁房间请求"""
path_parts = request["path"].split("/")
room_id = path_parts[-1] if len(path_parts) > 0 else None
if not room_id:
return {"error": "Missing room_id"}
if self.plugin.room_manager:
success = self.plugin.room_manager.destroy_room(room_id)
if success:
return {
"message": f"Room {room_id} destroyed successfully",
"timestamp": time.time()
}
else:
return {"error": "Failed to destroy room"}
else:
return {"error": "Room manager not available"}
def _handle_get_metrics(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理获取监控指标请求"""
metrics = {}
if self.plugin.monitoring_system:
metrics = self.plugin.monitoring_system.get_performance_metrics()
return {
"metrics": metrics,
"timestamp": time.time()
}
def _handle_get_alerts(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理获取警报信息请求"""
alerts = {}
alert_history = []
if self.plugin.monitoring_system:
alerts = self.plugin.monitoring_system.get_active_alerts()
alert_history = self.plugin.monitoring_system.get_alert_history()
return {
"active_alerts": alerts,
"alert_history": alert_history,
"timestamp": time.time()
}
def _handle_swagger_ui(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理Swagger UI请求"""
return {
"message": "Swagger UI would be served here",
"swagger_spec_url": "/api/swagger.json",
"timestamp": time.time()
}
def _handle_swagger_spec(self, request: Dict[str, Any]) -> Dict[str, Any]:
"""处理Swagger规范请求"""
spec = {
"swagger": "2.0",
"info": {
"title": "EG Server Architecture API",
"version": "1.0.0",
"description": "API for managing EG server architecture"
},
"paths": {
"/api/v1/system/info": {
"get": {
"summary": "Get system information",
"responses": {
"200": {
"description": "System information"
}
}
}
},
"/api/v1/system/stats": {
"get": {
"summary": "Get system statistics",
"responses": {
"200": {
"description": "System statistics"
}
}
}
}
# 这里可以继续添加更多API端点的规范
}
}
return spec
def get_api_stats(self) -> Dict[str, Any]:
"""
获取API统计信息
Returns:
API统计字典
"""
return {
"state": self.api_state.copy(),
"stats": self.api_stats.copy(),
"config": self.api_config.copy()
}
def reset_stats(self):
"""重置API统计信息"""
try:
self.api_stats = {
"requests_handled": 0,
"bytes_sent": 0,
"bytes_received": 0,
"average_response_time": 0.0,
"errors": 0
}
self.api_state["total_requests"] = 0
self.api_state["successful_requests"] = 0
self.api_state["failed_requests"] = 0
print("✓ API统计信息已重置")
except Exception as e:
print(f"✗ API统计信息重置失败: {e}")
def set_api_config(self, config: Dict[str, Any]) -> bool:
"""
设置API配置
Args:
config: API配置字典
Returns:
是否设置成功
"""
try:
old_port = self.api_config.get("api_port")
new_port = config.get("api_port", old_port)
# 如果端口发生变化,重启服务器
if old_port != new_port and self.api_state["is_running"]:
self._stop_http_server()
self.api_config.update(config)
self._start_http_server()
else:
self.api_config.update(config)
print(f"✓ API配置已更新: {self.api_config}")
return True
except Exception as e:
print(f"✗ API配置设置失败: {e}")
return False
def get_api_config(self) -> Dict[str, Any]:
"""
获取API配置
Returns:
API配置字典
"""
return self.api_config.copy()
def _trigger_api_callback(self, callback_type: str, data: Dict[str, Any]):
"""
触发API回调
Args:
callback_type: 回调类型
data: 回调数据
"""
try:
if callback_type in self.api_callbacks:
for callback in self.api_callbacks[callback_type]:
try:
callback(data)
except Exception as e:
print(f"✗ API回调执行失败: {callback_type} - {e}")
except Exception as e:
print(f"✗ API回调触发失败: {e}")
def register_api_callback(self, callback_type: str, callback: callable):
"""
注册API回调
Args:
callback_type: 回调类型
callback: 回调函数
"""
try:
if callback_type in self.api_callbacks:
self.api_callbacks[callback_type].append(callback)
print(f"✓ API回调已注册: {callback_type}")
else:
print(f"✗ 无效的回调类型: {callback_type}")
except Exception as e:
print(f"✗ API回调注册失败: {e}")
def unregister_api_callback(self, callback_type: str, callback: callable):
"""
注销API回调
Args:
callback_type: 回调类型
callback: 回调函数
"""
try:
if callback_type in self.api_callbacks:
if callback in self.api_callbacks[callback_type]:
self.api_callbacks[callback_type].remove(callback)
print(f"✓ API回调已注销: {callback_type}")
else:
print(f"✗ 无效的回调类型: {callback_type}")
except Exception as e:
print(f"✗ API回调注销失败: {e}")