use crate::types::*;
use async_trait::async_trait;
use ferrum_types::{InferenceRequest, Result};
use std::time::Duration;
#[async_trait]
pub trait HttpServer: Send + Sync {
async fn start(&self, config: &ServerConfig) -> Result<()>;
async fn stop(&self, timeout: Duration) -> Result<()>;
fn is_running(&self) -> bool;
fn address(&self) -> Option<std::net::SocketAddr>;
fn register_handler(
&mut self,
path: &str,
method: HttpMethod,
handler: Box<dyn RequestHandler>,
);
fn register_middleware(&mut self, middleware: Box<dyn Middleware>);
fn get_metrics(&self) -> ServerMetrics;
async fn health_check(&self) -> HealthStatus;
}
#[async_trait]
pub trait RequestHandler: Send + Sync {
async fn handle(&self, request: HttpRequest, context: RequestContext) -> Result<HttpResponse>;
fn name(&self) -> &str;
fn can_handle(&self, request: &HttpRequest) -> bool;
}
pub trait ResponseBuilder: Send + Sync {
fn ok(&self, body: serde_json::Value) -> HttpResponse;
fn error(&self, code: StatusCode, message: &str) -> HttpResponse;
fn streaming(&self, content_type: &str) -> HttpResponse;
fn with_headers(&self, body: serde_json::Value, headers: Headers) -> HttpResponse;
fn redirect(&self, location: &str, permanent: bool) -> HttpResponse;
}
#[async_trait]
pub trait StreamingHandler: Send + Sync {
async fn handle_stream(
&self,
request: InferenceRequest,
sender: Box<dyn StreamSender>,
) -> Result<()>;
fn stream_config(&self) -> &StreamConfig;
}
#[async_trait]
pub trait StreamSender: Send + Sync {
async fn send_chunk(&self, chunk: &str) -> Result<()>;
async fn send_json(&self, data: &serde_json::Value) -> Result<()>;
async fn close(&self) -> Result<()>;
fn is_closed(&self) -> bool;
}
#[async_trait]
pub trait Middleware: Send + Sync {
async fn before_request(
&self,
request: &mut HttpRequest,
context: &mut RequestContext,
) -> Result<()>;
async fn after_response(
&self,
request: &HttpRequest,
response: &mut HttpResponse,
context: &RequestContext,
) -> Result<()>;
async fn on_error(
&self,
error: &ferrum_types::FerrumError,
context: &RequestContext,
) -> Option<HttpResponse>;
fn name(&self) -> &str;
fn priority(&self) -> i32;
}
pub trait MiddlewareStack: Send + Sync {
fn add(&mut self, middleware: Box<dyn Middleware>);
fn remove(&mut self, name: &str) -> bool;
fn get(&self, name: &str) -> Option<&dyn Middleware>;
fn clear(&mut self);
fn len(&self) -> usize;
}
#[async_trait]
pub trait AuthProvider: Send + Sync {
async fn authenticate(&self, request: &HttpRequest) -> Result<AuthResult>;
async fn validate_api_key(&self, api_key: &str) -> Result<ClientInfo>;
async fn validate_jwt(&self, token: &str) -> Result<TokenClaims>;
fn scheme(&self) -> AuthScheme;
}
#[async_trait]
pub trait RateLimiter: Send + Sync {
async fn check_limit(&self, client_id: &str, endpoint: &str) -> Result<RateLimitResult>;
async fn record_request(&self, client_id: &str, endpoint: &str) -> Result<()>;
async fn get_status(&self, client_id: &str) -> Result<RateLimitStatus>;
async fn reset_limits(&self, client_id: &str) -> Result<()>;
}
pub trait RequestValidator: Send + Sync {
fn validate_inference_request(&self, request: &InferenceRequest) -> Result<()>;
fn validate_chat_request(&self, request: &crate::openai::ChatCompletionsRequest) -> Result<()>;
fn validate_parameters(&self, params: &serde_json::Value) -> Result<()>;
fn get_rules(&self) -> &ValidationRules;
}
#[async_trait]
pub trait HealthChecker: Send + Sync {
async fn check_health(&self) -> HealthStatus;
async fn check_component(&self, component: &str) -> ComponentHealth;
fn config(&self) -> &HealthCheckConfig;
}
#[async_trait]
pub trait MetricsCollector: Send + Sync {
async fn record_request(
&self,
request: &HttpRequest,
response: &HttpResponse,
duration: Duration,
);
async fn record_error(&self, error: &ferrum_types::FerrumError, endpoint: &str);
fn get_metrics(&self) -> ServerMetrics;
async fn reset_metrics(&self) -> Result<()>;
}
#[async_trait]
pub trait ServerLifecycle: Send + Sync {
async fn initialize(&self) -> Result<()>;
async fn start_services(&self) -> Result<()>;
async fn stop_services(&self, timeout: Duration) -> Result<()>;
async fn graceful_shutdown(&self, signal: ShutdownSignal) -> Result<()>;
fn get_state(&self) -> LifecycleState;
}