diff --git a/backend/basic/src/dto.rs b/backend/basic/src/dto.rs index 495549e63..d52394569 100644 --- a/backend/basic/src/dto.rs +++ b/backend/basic/src/dto.rs @@ -1,3 +1,4 @@ +//! Basic DTOs use std::collections::HashMap; use serde::{Deserialize, Serialize}; @@ -7,17 +8,25 @@ use crate::enumeration::BasicQueryOpKind; #[cfg(feature = "default")] use tardis::web::poem_openapi; +/// Basic query condition object +/// 基础的查询条件对象 #[derive(Serialize, Deserialize, Debug, Clone)] #[cfg_attr(feature = "default", derive(poem_openapi::Object))] pub struct BasicQueryCondInfo { + /// Query field #[oai(validator(min_length = "1"))] pub field: String, + /// Query operator pub op: BasicQueryOpKind, + /// Query value pub value: Value, } impl BasicQueryCondInfo { - // The outer level is the `OR` relationship, the inner level is the `AND` relationship + /// Check if the ``check_vars`` passed in meet the conditions in ``conds`` + /// 检查传入的 ``check_vars`` 是否满足 ``conds`` 中的条件 + /// + /// The outer level is the `OR` relationship, the inner level is the `AND` relationship pub fn check_or_and_conds(conds: &Vec>, check_vars: &HashMap) -> TardisResult { let is_match = conds.iter().any(|and_conds| { and_conds.iter().all(|cond| match check_vars.get(&cond.field) { @@ -93,7 +102,7 @@ mod tests { use tardis::{basic::result::TardisResult, serde_json::json}; - use crate::{enumeration::BasicQueryOpKind, dto::BasicQueryCondInfo}; + use crate::{dto::BasicQueryCondInfo, enumeration::BasicQueryOpKind}; #[test] fn test_check_or_and_conds() -> TardisResult<()> { diff --git a/backend/basic/src/enumeration.rs b/backend/basic/src/enumeration.rs index 2075ec03c..371582f66 100644 --- a/backend/basic/src/enumeration.rs +++ b/backend/basic/src/enumeration.rs @@ -1,25 +1,42 @@ +//! Basic enumerations use serde::{Deserialize, Serialize}; use tardis::derive_more::Display; #[cfg(feature = "default")] use tardis::web::poem_openapi; +/// API classification +/// API分类 #[derive(Display, Debug)] #[cfg_attr(feature = "default", derive(poem_openapi::Tags))] pub enum ApiTag { + /// Common Console, mostly starting with ``cc``, generally do not require authentication. + /// 公共类型, 多使用 ``cc`` 开头,一般不需要认证 #[oai(rename = "Common Console")] Common, + /// Tenant Console, mostly starting with ``ct`` + /// 租户类型, 多使用 ``ct`` 开头 #[oai(rename = "Tenant Console")] Tenant, + /// App Console, mostly starting with ``ca`` + /// 应用类型, 多使用 ``ca`` 开头 #[oai(rename = "App Console")] App, + /// System Console, mostly starting with ``cs`` + /// 系统类型, 多使用 ``cs`` 开头 #[oai(rename = "System Console")] System, + /// Passport Console, mostly starting with ``cp`` + /// 通行证类型, 多使用 ``cp`` 开头 #[oai(rename = "Passport Console")] Passport, + /// Interface Console, mostly starting with ``ci``, used for system-to-system calls, this type of interface generally uses ak/sk authentication + /// 接口类型, 多使用 ``ci`` 开头, 用于系统间调用, 此类型接口一般使用ak/sk认证 #[oai(rename = "Interface Console")] Interface, } +/// Basic query operator +/// 基础查询操作符 #[derive(Display, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[cfg_attr(feature = "default", derive(poem_openapi::Enum))] pub enum BasicQueryOpKind { diff --git a/backend/basic/src/lib.rs b/backend/basic/src/lib.rs index 2e0de9371..6cc10ed6f 100644 --- a/backend/basic/src/lib.rs +++ b/backend/basic/src/lib.rs @@ -1,7 +1,23 @@ +//! Basic library for BIOS +//! BIOS的基础库 +//! +//! This library provides the following functions: +//! 1. RBUM (Resource-Based Unified Model) model and implementation of common operations. +//! 1. SPI (Service Provider Interface) model and implementation of common operations. +//! 1. Common enumeration types. +//! 1. Common utility functions. +//! 1. Basic test support. +//! +//! 此类库提供了下功能: +//! 1. RBUM(基于资源的统一模型)模型及公共操作的实现 +//! 1. SPI(服务提供接口)模型及公共操作的实现 +//! 1. 通用枚举类型 +//! 1. 通用工具函数 +//! 1. 基础的测试支持 extern crate lazy_static; -pub mod enumeration; pub mod dto; +pub mod enumeration; pub mod helper; pub mod process; pub mod rbum; @@ -12,10 +28,19 @@ pub mod test; pub use enumeration::ApiTag; use tardis::{TardisFuns, TardisFunsInst}; +/// Extractor for ``TardisFunInst`` +/// 提取 ``TardisFunsInst`` pub trait TardisFunInstExtractor { fn tardis_fun_inst(&self) -> TardisFunsInst; } +/// Extract ``TardisFunInst`` from request path +/// 从请求路径中自动提取 ``TardisFunInst`` +/// +/// Get the first path segment from the request path as the service domain. +/// If there is a configuration parameter ``csm.X`` with the same name as the service domain, use this configuration parameter, +/// otherwise use the default configuration parameter. +/// 从请求路径中找到第一个路径段作为服务域名,如果存在与该服务域名同名的配置参数 ``csm.X``, 则使用该配置参数,否则使用默认配置参数. #[cfg(feature = "default")] impl TardisFunInstExtractor for tardis::web::poem::Request { fn tardis_fun_inst(&self) -> TardisFunsInst { diff --git a/backend/basic/src/process/ci_processor.rs b/backend/basic/src/process/ci_processor.rs index 237c6d4ad..2637b4cc6 100644 --- a/backend/basic/src/process/ci_processor.rs +++ b/backend/basic/src/process/ci_processor.rs @@ -1,8 +1,13 @@ +//! CI (Interface Console) Processor +//! +//! The CI type interface is mostly used for calls between systems, and the interface is authenticated by Ak/Sk to ensure the security of the interface. +//! CI类型的接口多用于系统之间的调用,通过Ak/Sk进行签名认证,保证接口的安全性。 use serde::{Deserialize, Serialize}; use tardis::{basic::result::TardisResult, chrono::Utc, TardisFuns}; use crate::helper::request_helper::sort_query; +/// Application key configuration #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(default)] pub struct AppKeyConfig { @@ -21,7 +26,9 @@ impl Default for AppKeyConfig { } } -// signature ak +/// Generate signature +/// +/// Generate a signature for the request and return the request header with the signature pub fn signature(app_key_config: &AppKeyConfig, method: &str, path: &str, query: &str, mut header: Vec<(String, String)>) -> TardisResult> { let sorted_req_query = sort_query(query); let date = Utc::now().format("%a, %d %b %Y %T GMT").to_string(); diff --git a/backend/basic/src/process/task_processor.rs b/backend/basic/src/process/task_processor.rs index 87708ef22..5ddb65add 100644 --- a/backend/basic/src/process/task_processor.rs +++ b/backend/basic/src/process/task_processor.rs @@ -1,5 +1,4 @@ -//! # 异步任务处理器 - +//! Async task processor use std::{collections::HashMap, future::Future, sync::Arc}; use lazy_static::lazy_static; @@ -21,16 +20,20 @@ lazy_static! { const TASK_PROCESSOR_DATA_EX_SEC: u64 = 60 * 60 * 24; const TASK_IN_CTX_FLAG: &str = "task_id"; +/// Set task status event flag /// 设置任务状态事件标识 pub const EVENT_SET_TASK_STATUS_FLAG: &str = "set_task_status"; +/// Set task process data event flag /// 设置任务处理数据事件标识 pub const EVENT_SET_TASK_PROCESS_DATA_FLAG: &str = "set_task_process"; +/// Execute task event flag /// 执行任务事件标识 pub const EVENT_EXECUTE_TASK_FLAG: &str = "execute_task"; pub struct TaskProcessor; impl TaskProcessor { + /// Initialize the asynchronous task status /// 初始化异步任务状态 pub async fn init_status(cache_key: &str, task_id: Option, cache_client: &TardisCacheClient) -> TardisResult { let task_id = task_id.unwrap_or(Local::now().timestamp_nanos_opt().expect("maybe in 23rd century") as u64); @@ -44,6 +47,7 @@ impl TaskProcessor { Ok(task_id) } + /// Check the status of the asynchronous task (whether it is completed) /// 检查异步任务状态(是否完成) pub async fn check_status(cache_key: &str, task_id: u64, cache_client: &TardisCacheClient) -> TardisResult { let result1 = cache_client.getbit(&format!("{cache_key}:1"), (task_id / u32::MAX as u64) as usize).await?; @@ -51,6 +55,7 @@ impl TaskProcessor { Ok(result1 && result2) } + /// Set the status of the asynchronous task (whether it is completed) /// 设置异步任务状态(是否完成) pub async fn set_status(cache_key: &str, task_id: u64, status: bool, cache_client: &TardisCacheClient) -> TardisResult<()> { cache_client.setbit(&format!("{cache_key}:1"), (task_id / u32::MAX as u64) as usize, status).await?; @@ -58,6 +63,7 @@ impl TaskProcessor { Ok(()) } + /// Set the status of the asynchronous task (whether it is completed) and send an event /// 设置异步任务状态(是否完成)并发送事件 pub async fn set_status_with_event( cache_key: &str, @@ -83,12 +89,14 @@ impl TaskProcessor { .await } + /// Set the processing data of the asynchronous task /// 设置异步任务处理数据 pub async fn set_process_data(cache_key: &str, task_id: u64, data: Value, cache_client: &TardisCacheClient) -> TardisResult<()> { cache_client.set_ex(&format!("{cache_key}:{task_id}"), &TardisFuns::json.json_to_string(data)?, TASK_PROCESSOR_DATA_EX_SEC).await?; Ok(()) } + /// Set the processing data of the asynchronous task and send an event /// 设置异步任务处理数据并发送事件 pub async fn set_process_data_with_event( cache_key: &str, @@ -115,6 +123,7 @@ impl TaskProcessor { Ok(()) } + /// Fetch the processing data of the asynchronous task /// 获取异步任务处理数据 pub async fn get_process_data(cache_key: &str, task_id: u64, cache_client: &TardisCacheClient) -> TardisResult { if let Some(result) = cache_client.get(&format!("{cache_key}:{task_id}")).await? { @@ -124,6 +133,7 @@ impl TaskProcessor { } } + /// Execute asynchronous task /// 执行异步任务 pub async fn execute_task(cache_key: &str, process_fun: P, cache_client: &Arc) -> TardisResult where @@ -133,6 +143,7 @@ impl TaskProcessor { Self::do_execute_task_with_ctx(cache_key, process_fun, cache_client, None, "".to_string(), None, None).await } + /// Execute asynchronous task and send event /// 执行异步任务并发送事件 pub async fn execute_task_with_ctx( cache_key: &str, @@ -204,6 +215,7 @@ impl TaskProcessor { Ok(task_id) } + /// Execute asynchronous task (without asynchronous function, only used to mark the start of the task) /// 执行异步任务(不带异步函数,仅用于标记任务开始执行) pub async fn execute_task_without_fun( cache_key: &str, @@ -229,11 +241,13 @@ impl TaskProcessor { Ok(task_id) } + /// Stop asynchronous task /// 停止异步任务 pub async fn stop_task(cache_key: &str, task_id: u64, cache_client: &TardisCacheClient) -> TardisResult<()> { Self::stop_task_with_event(cache_key, task_id, cache_client, None, "".to_string(), None).await } + /// Stop asynchronous task and send event /// 停止异步任务并发送事件 pub async fn stop_task_with_event( cache_key: &str, @@ -262,8 +276,10 @@ impl TaskProcessor { Ok(()) } + /// Fetch the asynchronous task IDs in the context /// 获取异步任务IDs /// + /// Use ``,`` to separate multiple tasks /// 多个任务使用``,``分隔 pub async fn get_task_id_with_ctx(ctx: &TardisContext) -> TardisResult> { ctx.get_ext(TASK_IN_CTX_FLAG).await @@ -285,7 +301,7 @@ impl TaskProcessor { } #[derive(Clone, Debug, Deserialize, Serialize)] -pub struct TaskWsEventReq { +struct TaskWsEventReq { pub task_id: u64, pub data: Value, pub msg: String, diff --git a/backend/basic/src/test.rs b/backend/basic/src/test.rs index 0c4e15cc5..902ed0352 100644 --- a/backend/basic/src/test.rs +++ b/backend/basic/src/test.rs @@ -1,3 +1,4 @@ #[cfg(feature = "default")] pub mod init_rbum_test_container; +#[cfg(feature = "default")] pub mod test_http_client; diff --git a/backend/basic/src/test/init_rbum_test_container.rs b/backend/basic/src/test/init_rbum_test_container.rs index aefa3f33e..d59edf126 100644 --- a/backend/basic/src/test/init_rbum_test_container.rs +++ b/backend/basic/src/test/init_rbum_test_container.rs @@ -1,3 +1,4 @@ +//! Init test container use std::env; use tardis::basic::result::TardisResult; @@ -15,9 +16,6 @@ pub struct LifeHold<'a> { } pub async fn init(docker: &Cli, sql_init_path: Option) -> TardisResult> { - // let reldb_container = TardisTestContainer::mysql_custom(None, docker); - // let port = reldb_container.get_host_port_ipv4(3306); - // let url = format!("mysql://root:123456@127.0.0.1:{}/test", port); let reldb_container = TardisTestContainer::postgres_custom(sql_init_path.as_deref(), docker); let port = reldb_container.get_host_port_ipv4(5432); let url = format!("postgres://postgres:123456@127.0.0.1:{port}/test"); diff --git a/backend/basic/src/test/test_http_client.rs b/backend/basic/src/test/test_http_client.rs index 5dcec5a34..2a0c8753e 100644 --- a/backend/basic/src/test/test_http_client.rs +++ b/backend/basic/src/test/test_http_client.rs @@ -1,3 +1,4 @@ +//! Http client for testing use std::fmt::Debug; use serde::de::DeserializeOwned; @@ -30,6 +31,8 @@ impl TestHttpClient { } } + /// Build a request with authentication information + /// 构造一个带有认证信息的请求 pub fn set_auth(&mut self, ctx: &TardisContext) -> TardisResult<()> { let ctx_base64 = &TardisFuns::crypto.base64.encode(TardisFuns::json.obj_to_string(&ctx)?); let fw_config = TardisFuns::fw_config();