use crate::ApiRouter;
use appcore_core::{RuntimeController, RuntimeOperationalMode};
use parking_lot::Mutex;
use std::sync::atomic::AtomicU64;
use std::sync::Arc;
use super::auth::HttpCommandAuth;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HttpApiConfig {
pub host: String,
pub port: u16,
pub enabled: bool,
pub max_payload_bytes: usize,
}
impl Default for HttpApiConfig {
fn default() -> Self {
Self {
host: "127.0.0.1".to_string(),
port: 8080,
enabled: false,
max_payload_bytes: 65_536,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
pub struct RuntimeStaticInfo {
pub app_id: String,
pub node_id: String,
pub tenant_id: String,
pub cluster_id: String,
pub core_id: String,
pub operation_mode: String,
pub storage_status: String,
pub security_ok: bool,
pub api_enabled: bool,
pub sync_enabled: bool,
pub sync_role: String,
pub sync_log_len: usize,
pub sync_log_path: Option<String>,
pub sync_checkpoint_path: Option<String>,
pub sync_peers: Vec<String>,
pub sync_dns_enabled: bool,
pub sync_dns_seeds: Vec<String>,
pub sync_dns_default_port: u16,
pub idempotency_ttl_ms: u64,
pub idempotency_path: Option<String>,
}
#[derive(Clone)]
pub(crate) struct HttpState {
pub(crate) static_info: RuntimeStaticInfo,
pub(crate) controller: Option<Arc<Mutex<RuntimeController>>>,
pub(crate) app_query_router: Option<Arc<Mutex<ApiRouter>>>,
pub(crate) sync_log: Option<Arc<dyn SyncLogView>>,
pub(crate) tick_counter: Option<Arc<AtomicU64>>,
pub(crate) operation_mode: Option<Arc<Mutex<RuntimeOperationalMode>>>,
pub(crate) command_policy: Option<Arc<dyn CommandCapabilityPolicy>>,
pub(crate) supervisor: Option<appcore_supervisor::Supervisor>,
pub(crate) auth: HttpCommandAuth,
pub(crate) max_payload_bytes: usize,
pub(crate) clock: Arc<dyn appcore_core::Clock>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CommandCapabilityPolicyError {
CapabilityNotDeclared,
MissingIdempotencyKey,
RequiresLeader,
LeaseExpired,
StaleEpoch,
ReadOnly,
Rejected(String),
}
pub trait CommandCapabilityPolicy: Send + Sync {
fn authorize_command(
&self,
command_name: &str,
idempotency_key: Option<&str>,
now_ms: u64,
) -> Result<(), CommandCapabilityPolicyError>;
fn authorize_query(
&self,
_query_name: &str,
_now_ms: u64,
) -> Result<(), CommandCapabilityPolicyError> {
Ok(())
}
}
pub trait SyncLogView: Send + Sync {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}