secra_plugins 0.1.32

生产级插件系统 - 插件的生命周期
Documentation

use crate::config::{PluginConfiguration, PluginConfig};
use crate::lifecycle::PluginLifecycle;
use crate::metadata::PluginMetadata;
use async_trait::async_trait;
use crate::error::PluginManagerResult;
use actix_web::web;


/// 所有插件必须实现此 trait
///
/// 插件主接口,定义了插件必须实现的所有核心功能。
/// 插件必须同时实现 `PluginConfiguration` 和 `PluginLifecycle` trait。
///
/// # 要求
/// * `PluginConfiguration`: 插件必须支持配置管理
/// * `PluginLifecycle`: 插件必须支持生命周期钩子
/// * `Send + Sync`: 插件必须可以在线程间安全传递和共享
///
/// # 生命周期
/// 1. **加载** (Loaded): 插件已加载到内存
/// 2. **初始化** (Initialized): 调用 `initialize()` 后
/// 3. **运行** (Running): 调用 `start()` 后
/// 4. **停止** (Stopped): 调用 `stop()` 后
///
/// # 实现
/// 插件开发者必须实现此 trait 的所有方法(除了有默认实现的方法)。
///
/// # 示例
/// ```no_run
/// struct MyPlugin {
///     metadata: PluginMetadata,
///     config: PluginConfig,
/// }
///
/// #[async_trait]
/// impl Plugin for MyPlugin {
///     fn metadata(&self) -> &PluginMetadata {
///         &self.metadata
///     }
///
///     async fn initialize(&mut self, config: PluginConfig) -> PluginManagerResult<()> {
///         self.config = config;
///         Ok(())
///     }
///
///     async fn start(&mut self) -> PluginManagerResult<()> {
///         // 启动逻辑
///         Ok(())
///     }
///
///     async fn stop(&mut self) -> PluginManagerResult<()> {
///         // 停止逻辑
///         Ok(())
///     }
///
///     async fn execute(&self, action: &str, params: serde_json::Value) -> PluginManagerResult<serde_json::Value> {
///         // 执行逻辑
///         Ok(serde_json::json!({}))
///     }
/// }
/// ```
#[async_trait]
pub trait Plugin: PluginConfiguration + PluginLifecycle + Send + Sync {
    /// 获取插件元数据
    ///
    /// 返回插件的元数据引用,包含插件的ID、名称、版本等信息。
    ///
    /// # 返回值
    /// * `&PluginMetadata` - 插件元数据的不可变引用
    ///
    /// # 注意
    /// 元数据在插件生命周期内应该保持不变。
    fn metadata(&self) -> &PluginMetadata;

    /// 初始化插件
    ///
    /// 初始化插件,设置插件的配置。插件必须处于 `Loaded` 状态才能初始化。
    /// 初始化后插件状态变为 `Initialized`。
    ///
    /// # 参数
    /// * `config` - 插件配置对象,包含启用状态、设置参数等
    ///
    /// # 返回值
    /// * `PluginManagerResult<()>` - 初始化成功返回 `Ok(())`
    ///
    /// # 错误
    /// * `PluginManagerError::InitializationFailed` - 如果初始化失败
    ///
    /// # 状态转换
    /// * `Loaded` -> `Initialized`: 初始化成功
    /// * `Loaded` -> `Error`: 初始化失败
    ///
    /// # 行为
    /// * 插件应该根据配置进行初始化
    /// * 可以分配资源、建立连接等
    /// * 初始化失败应该清理已分配的资源
    async fn initialize(&mut self, config: PluginConfig) -> PluginManagerResult<()>;

    /// 启动插件
    ///
    /// 启动插件,使插件进入运行状态。插件必须处于 `Initialized` 或 `Stopped` 状态才能启动。
    /// 启动后插件状态变为 `Running`。
    ///
    /// # 返回值
    /// * `PluginManagerResult<()>` - 启动成功返回 `Ok(())`
    ///
    /// # 错误
    /// * `PluginManagerError::StartFailed` - 如果启动失败
    ///
    /// # 状态转换
    /// * `Initialized` -> `Running`: 启动成功
    /// * `Stopped` -> `Running`: 重新启动成功
    /// * `Initialized` -> `Error`: 启动失败
    ///
    /// # 行为
    /// * 插件应该启动服务、开始处理请求等
    /// * 启动前会调用 `on_before_start()` 钩子
    /// * 启动成功后会调用 `on_after_start()` 钩子
    async fn start(&mut self) -> PluginManagerResult<()>;

    /// 停止插件
    ///
    /// 停止插件,使插件退出运行状态。插件必须处于 `Running` 状态才能停止。
    /// 停止后插件状态变为 `Stopped`。
    ///
    /// # 返回值
    /// * `PluginManagerResult<()>` - 停止成功返回 `Ok(())`
    ///
    /// # 错误
    /// * `PluginManagerError::StopFailed` - 如果停止失败
    ///
    /// # 状态转换
    /// * `Running` -> `Stopped`: 停止成功
    /// * `Running` -> `Error`: 停止失败
    ///
    /// # 行为
    /// * 插件应该停止服务、关闭连接、清理资源等
    /// * 停止前会调用 `on_before_stop()` 钩子
    /// * 停止成功后会调用 `on_after_stop()` 钩子
    async fn stop(&mut self) -> PluginManagerResult<()>;

    /// 执行插件功能
    ///
    /// 执行插件的特定功能操作。插件必须处于 `Running` 状态才能执行。
    ///
    /// # 参数
    /// * `action` - 要执行的动作名称,由插件定义
    /// * `params` - 执行参数,使用 JSON 格式传递
    ///
    /// # 返回值
    /// * `PluginManagerResult<serde_json::Value>` - 执行成功返回结果(JSON 格式)
    ///
    /// # 错误
    /// * `PluginManagerError::StateError` - 如果插件未处于运行状态
    /// * `PluginManagerError::ExecutionError` - 如果执行失败或超时
    ///
    /// # 行为
    /// * 插件根据 `action` 参数执行相应的功能
    /// * 参数和返回值都使用 JSON 格式,便于序列化和传输
    /// * 执行过程有超时保护
    ///
    /// # 示例
    /// ```no_run
    /// let params = serde_json::json!({"key": "value"});
    /// let result = plugin.execute("my_action", params).await?;
    /// ```
    async fn execute(
        &self,
        action: &str,
        params: serde_json::Value,
    ) -> PluginManagerResult<serde_json::Value>;

    /// 注册插件路由(如果插件支持路由)
    ///
    /// 为插件注册 HTTP 路由。只有配置了 `route_prefix` 的插件才会调用此方法。
    /// 插件可以重写此方法来注册自定义路由。
    ///
    /// # 参数
    /// * `cfg` - Actix Web 的服务配置对象,用于注册路由
    ///
    /// # 返回值
    /// * `PluginManagerResult<()>` - 注册成功返回 `Ok(())`
    ///
    /// # 错误
    /// * `PluginManagerError::ConfigError` - 如果路由注册失败
    ///
    /// # 默认实现
    /// 默认实现只记录警告日志,不执行任何操作。
    /// 如果插件需要注册路由,应该重写此方法。
    ///
    /// # 注意
    /// 此方法在插件状态为 `Running` 时调用,用于注册 HTTP 路由。
    /// 如果插件不需要 HTTP 路由功能,可以不重写此方法。
    ///
    /// # 示例
    /// ```no_run
    /// fn register_routes(&self, cfg: &mut web::ServiceConfig) -> PluginManagerResult<()> {
    ///     cfg.service(
    ///         web::scope(&self.metadata().route_prefix.unwrap())
    ///             .route("/hello", web::get().to(hello_handler))
    ///     );
    ///     Ok(())
    /// }
    /// ```
    fn register_routes(&self, _cfg: &mut web::ServiceConfig) -> PluginManagerResult<()> {
        // 默认实现:如果插件支持路由但没有实现 PluginRoutes,
        // 可以通过类型转换来调用
        // 注意:如果插件重写了这个方法,这个默认实现不会被调用
        tracing::warn!(
            "插件 {} 使用了默认的 register_routes 实现(可能没有正确重写)",
            self.metadata().id
        );
        Ok(())
    }
}