From e21fe2b4332f89af9f8cefdeff5c7ef17146da1e Mon Sep 17 00:00:00 2001 From: 4t145 Date: Wed, 28 Feb 2024 18:22:22 +0800 Subject: [PATCH 1/2] fix cert problem in web server test --- tardis/tests/config/conf-default.toml | 1 + tardis/tests/test_web_server.rs | 103 +++++++++++++------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/tardis/tests/config/conf-default.toml b/tardis/tests/config/conf-default.toml index 9053966d..e5c235aa 100644 --- a/tardis/tests/config/conf-default.toml +++ b/tardis/tests/config/conf-default.toml @@ -11,5 +11,6 @@ default_lang = "zh-CN" [fw.log] level = "debug" # directives = ["tokio=trace", "runtime=trace"] +directives = ["poem=debug"] tracing_appender = { rotation = "minutely", dir = "./tests/log", filename = "app.log" } tracing = { endpoint = "http://localhost:4317", protocol = "grpc", server_name = "tardis-test" } diff --git a/tardis/tests/test_web_server.rs b/tardis/tests/test_web_server.rs index 0742ea91..359e627b 100644 --- a/tardis/tests/test_web_server.rs +++ b/tardis/tests/test_web_server.rs @@ -3,6 +3,7 @@ extern crate core; use std::env; +use std::str::FromStr; use std::time::Duration; use async_trait::async_trait; @@ -19,7 +20,7 @@ use tardis::basic::dto::TardisContext; use tardis::basic::error::TardisError; use tardis::basic::field::TrimString; use tardis::basic::result::{TardisResult, TARDIS_RESULT_ACCEPTED_CODE, TARDIS_RESULT_SUCCESS_CODE}; -use tardis::config::config_dto::{CacheModuleConfig, FrameworkConfig, TardisConfig, WebClientConfig, WebServerCommonConfig, WebServerConfig, WebServerModuleConfig}; +use tardis::config::config_dto::{CacheModuleConfig, FrameworkConfig, LogConfig, TardisConfig, WebClientConfig, WebServerCommonConfig, WebServerConfig, WebServerModuleConfig}; use tardis::serde::{Deserialize, Serialize}; use tardis::test::test_container::TardisTestContainer; use tardis::web::context_extractor::{TardisContextExtractor, TOKEN_FLAG}; @@ -34,62 +35,57 @@ mod helloworld_grpc { } pub use helloworld_grpc::*; use poem_grpc::{Request as GrpcRequest, Response as GrpcResponse, Status as GrpcStatus}; +use tracing_subscriber::filter::Directive; const TLS_KEY: &str = r#" ------BEGIN CERTIFICATE----- -MIIEADCCAmigAwIBAgICAcgwDQYJKoZIhvcNAQELBQAwLDEqMCgGA1UEAwwhcG9u -eXRvd24gUlNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMB4XDTE2MDgxMzE2MDcwNFoX -DTIyMDIwMzE2MDcwNFowGTEXMBUGA1UEAwwOdGVzdHNlcnZlci5jb20wggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpVhh1/FNP2qvWenbZSghari/UThwe -dynfnHG7gc3JmygkEdErWBO/CHzHgsx7biVE5b8sZYNEDKFojyoPHGWK2bQM/FTy -niJCgNCLdn6hUqqxLAml3cxGW77hAWu94THDGB1qFe+eFiAUnDmob8gNZtAzT6Ky -b/JGJdrEU0wj+Rd7wUb4kpLInNH/Jc+oz2ii2AjNbGOZXnRz7h7Kv3sO9vABByYe -LcCj3qnhejHMqVhbAT1MD6zQ2+YKBjE52MsQKU/xhUpu9KkUyLh0cxkh3zrFiKh4 -Vuvtc+n7aeOv2jJmOl1dr0XLlSHBlmoKqH6dCTSbddQLmlK7dms8vE01AgMBAAGj -gb4wgbswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFMeUzGYV -bXwJNQVbY1+A8YXYZY8pMEIGA1UdIwQ7MDmAFJvEsUi7+D8vp8xcWvnEdVBGkpoW -oR6kHDAaMRgwFgYDVQQDDA9wb255dG93biBSU0EgQ0GCAXswOwYDVR0RBDQwMoIO -dGVzdHNlcnZlci5jb22CFXNlY29uZC50ZXN0c2VydmVyLmNvbYIJbG9jYWxob3N0 -MA0GCSqGSIb3DQEBCwUAA4IBgQBsk5ivAaRAcNgjc7LEiWXFkMg703AqDDNx7kB1 -RDgLalLvrjOfOp2jsDfST7N1tKLBSQ9bMw9X4Jve+j7XXRUthcwuoYTeeo+Cy0/T -1Q78ctoX74E2nB958zwmtRykGrgE/6JAJDwGcgpY9kBPycGxTlCN926uGxHsDwVs -98cL6ZXptMLTR6T2XP36dAJZuOICSqmCSbFR8knc/gjUO36rXTxhwci8iDbmEVaf -BHpgBXGU5+SQ+QM++v6bHGf4LNQC5NZ4e4xvGax8ioYu/BRsB/T3Lx+RlItz4zdU -XuxCNcm3nhQV2ZHquRdbSdoyIxV5kJXel4wCmOhWIq7A2OBKdu5fQzIAzzLi65EN -RPAKsKB4h7hGgvciZQ7dsMrlGw0DLdJ6UrFyiR5Io7dXYT/+JP91lP5xsl6Lhg9O -FgALt7GSYRm2cZdgi9pO9rRr83Br1VjQT1vHz6yoZMXSqc4A2zcN2a2ZVq//rHvc -FZygs8miAhWPzqnpmgTj1cPiU1M= ------END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCq4QyODxghypMz +u3wSNYAH7qsekRasbkFWlzRlfCkVfxMynGh8uRfNod4UrHAWTXDJAneHoFgqXemI +Vf1z87r0T2NFf3+oochAKvE6z9hNSeBbLIeZXPQQcabtO9T5cS4anK3k0mbgRpdM +bDhv4p+fbwCp6gOA/qeqs58p/f5UoXYVcjKmSQQAA5KSm4bPbBl89fiUFv1Rcp5H +L+sMIkFpwq8lYnEqKvV/1V8isMvhVDUo7MrIUwgqn6+n7KJIIsugOqxVKrYA4E6R +oFC1V3O5jdTrDvWhzlHel5VWHX6rG/4J4GvD+6nMZ2CvgK8DeW/vEsRUlPDPoTc0 +QRftHEO3AgMBAAECggEAGJC42tVNrVHvfoDl8cIyMTG89Ox7u3cwOnALTsmeKGJ3 +0o9MsB110BCEmik+Bd7FJ4iMwXkqI5ETqQ9fm+M+ja+6ADw3kHkNjjf+LOvDVz0X +HVRV/BSyW4jTLAitcdy0+YtrrlkXBAfx6UEnjeIg+20cRdEIBuvVE8O1znYesXC2 +oALXl2f1lJE8n83rijn5ecxuJIM3fKt/tgfMPEfyz7OqY3USKGzaDUZyScLW1b0V +D2m1os7lzEuIkqK6JuunZpx36EEBTyWFFwnU/sobyL0h70qTXrtjZoO5qgOTS9rd +CkKAlXYessSTsH8L0jSZKMMp3Ho6y91b9VFxyfU6LQKBgQDMlDSuQhFqrNHcmtN0 +2adrJ15gJRJZzvsChaZd5PPVV4a55QAm5OOo5eA+zX/9/qHPjlgWigbDyyz+Nvx4 +Bl55XDJpkErrcdAgLyd81Dtzd5BQI5cSC/wSZdXJjw7RngmEfa9IscpiG8vs0MZJ +Tw56JjY1ue4vMwKOP4mndQ3GWwKBgQDV1GaZKFsq1GpDjzyIetedQ1JV/IGIygZY +ekPjla825EmDq23A5zkFYWK8aoRh44OnMmj7sP1UcJWgTgAiYvnowAVrvPuudX/F +DR0UsdBaOmJqsjuy6Xn9cldN85zbqpVS61+6OrNEGzHx//5i5jLr9zw2XAt9GGWo +fTsVkWvO1QKBgF9dPul0VtYZVYK2kZfI1ig3I+FBprpCp/PXBWSDk76BnIYPX/DB +hfZ3of7koKNwDVHJkvp+wQSIM6MVUr9IiMWd2somvyXd2h0Gniusa0I6HAWfcY6y +E4EoA25/x3KjbuBaDlmety7gskDkWWpW9fKu2VpWH9fUuX5B1BNBl3g9AoGBANVD +5qBS07q/6MxBDArDGlFLV89S7I7Vj8anCxbtr7d7sKaWT/zZoNFw890gD7DiDeiw +Kmz9dWzGbTVZFmE1fjNZcQ6nig3SOwD5t0twnXGgUZBA+7HRk03owJKKqqOcWxo8 +j1laOnlu9j17KOjS127pQzCkVQELWDjXzhoQ1AmRAoGACFk2lgato0S/PTdHhsOa +0G4zCbIpjndRYuW5IMURpiGeQEZ5unIuX72lx180ncj+PTw6DxxiEsESDhIp1VfW +RWf7YsEUgQICLka42SY+UsSfEe7Wya3ZM4bhc+wVi2rgjVBriuBC5UzMAWpCyMri +7A2laBCqWVkgks5BQPLtlXg= +-----END RSA PRIVATE KEY----- "#; const TLS_CERT: &str = r#" ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAqVYYdfxTT9qr1np22UoIWq4v1E4cHncp35xxu4HNyZsoJBHR -K1gTvwh8x4LMe24lROW/LGWDRAyhaI8qDxxlitm0DPxU8p4iQoDQi3Z+oVKqsSwJ -pd3MRlu+4QFrveExwxgdahXvnhYgFJw5qG/IDWbQM0+ism/yRiXaxFNMI/kXe8FG -+JKSyJzR/yXPqM9ootgIzWxjmV50c+4eyr97DvbwAQcmHi3Ao96p4XoxzKlYWwE9 -TA+s0NvmCgYxOdjLEClP8YVKbvSpFMi4dHMZId86xYioeFbr7XPp+2njr9oyZjpd -Xa9Fy5UhwZZqCqh+nQk0m3XUC5pSu3ZrPLxNNQIDAQABAoIBAFKtZJgGsK6md4vq -kyiYSufrcBLaaEQ/rkQtYCJKyC0NAlZKFLRy9oEpJbNLm4cQSkYPXn3Qunx5Jj2k -2MYz+SgIDy7f7KHgr52Ew020dzNQ52JFvBgt6NTZaqL1TKOS1fcJSSNIvouTBerK -NCSXHzfb4P+MfEVe/w1c4ilE+kH9SzdEo2jK/sRbzHIY8TX0JbmQ4SCLLayr22YG -usIxtIYcWt3MMP/G2luRnYzzBCje5MXdpAhlHLi4TB6x4h5PmBKYc57uOVNngKLd -YyrQKcszW4Nx5v0a4HG3A5EtUXNCco1+5asXOg2lYphQYVh2R+1wgu5WiDjDVu+6 -EYgjFSkCgYEA0NBk6FDoxE/4L/4iJ4zIhu9BptN8Je/uS5c6wRejNC/VqQyw7SHb -hRFNrXPvq5Y+2bI/DxtdzZLKAMXOMjDjj0XEgfOIn2aveOo3uE7zf1i+njxwQhPu -uSYA9AlBZiKGr2PCYSDPnViHOspVJjxRuAgyWM1Qf+CTC0D95aj0oz8CgYEAz5n4 -Cb3/WfUHxMJLljJ7PlVmlQpF5Hk3AOR9+vtqTtdxRjuxW6DH2uAHBDdC3OgppUN4 -CFj55kzc2HUuiHtmPtx8mK6G+otT7Lww+nLSFL4PvZ6CYxqcio5MPnoYd+pCxrXY -JFo2W7e4FkBOxb5PF5So5plg+d0z/QiA7aFP1osCgYEAtgi1rwC5qkm8prn4tFm6 -hkcVCIXc+IWNS0Bu693bXKdGr7RsmIynff1zpf4ntYGpEMaeymClCY0ppDrMYlzU -RBYiFNdlBvDRj6s/H+FTzHRk2DT/99rAhY9nzVY0OQFoQIXK8jlURGrkmI/CYy66 -XqBmo5t4zcHM7kaeEBOWEKkCgYAYnO6VaRtPNQfYwhhoFFAcUc+5t+AVeHGW/4AY -M5qlAlIBu64JaQSI5KqwS0T4H+ZgG6Gti68FKPO+DhaYQ9kZdtam23pRVhd7J8y+ -xMI3h1kiaBqZWVxZ6QkNFzizbui/2mtn0/JB6YQ/zxwHwcpqx0tHG8Qtm5ZAV7PB -eLCYhQKBgQDALJxU/6hMTdytEU5CLOBSMby45YD/RrfQrl2gl/vA0etPrto4RkVq -UrkDO/9W4mZORClN3knxEFSTlYi8YOboxdlynpFfhcs82wFChs+Ydp1eEsVHAqtu -T+uzn0sroycBiBfVB949LExnzGDFUkhG0i2c2InarQYLTsIyHCIDEA== ------END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIICrzCCAZcCFBAFc1XYPWC+wosehbOnnxfi0t2KMA0GCSqGSIb3DQEBCwUAMBQx +EjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yNDAyMjgxMDAwMTdaFw0yNTAyMjcxMDAw +MTdaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAKrhDI4PGCHKkzO7fBI1gAfuqx6RFqxuQVaXNGV8KRV/EzKcaHy5 +F82h3hSscBZNcMkCd4egWCpd6YhV/XPzuvRPY0V/f6ihyEAq8TrP2E1J4Fssh5lc +9BBxpu071PlxLhqcreTSZuBGl0xsOG/in59vAKnqA4D+p6qznyn9/lShdhVyMqZJ +BAADkpKbhs9sGXz1+JQW/VFynkcv6wwiQWnCryVicSoq9X/VXyKwy+FUNSjsyshT +CCqfr6fsokgiy6A6rFUqtgDgTpGgULVXc7mN1OsO9aHOUd6XlVYdfqsb/gnga8P7 +qcxnYK+ArwN5b+8SxFSU8M+hNzRBF+0cQ7cCAwEAATANBgkqhkiG9w0BAQsFAAOC +AQEAXWK8bSNLcmnHByh0gt+i2tuH4luSopz95Sj2a2rbVVcnKUTy5vzhRgSc0uMr +dCoOB67X2vDfN7DU3ZGUEjgVA3mwntW19Vv03DBvZBsYY9uzZdv8NXDSRRiKNbU4 +dXS3HhsPFdbgx1zjmbjOU5/JEkw4d6Ijcy09mCqiaJd1IVLCKvvAfOXkAG91iWpQ +ZDloEhXbOC4/jzxi9cvNWIOf/DpqdcMMXAMOd92ubmuYV5YhusvCL/9rv9cQsm7q +bY588beOczzrXB0ldJAHZkoQFccSM1sP7pmUqgBOR0ZedmMzR37GuKjEpc/TvXHR +5TSjY7LCQ8H807/6Fil5WUDSZg== +-----END CERTIFICATE----- "#; #[tokio::test(flavor = "multi_thread")] @@ -136,6 +132,9 @@ async fn start_serv(web_url: &str, redis_url: &str) -> TardisResult<()> { .build(), ) .cache(CacheModuleConfig::builder().url(redis_url.parse().expect("invalid redis url")).build()) + .log(LogConfig::builder().directives([ + Directive::from_str("poem=debug").expect("invalid directives") + ]).level(Directive::from_str("info").expect("invalid directives")).build()) .build(); TardisFuns::init_conf(TardisConfig { cs: Default::default(), From 46159fbbd5e16724954a0815fd10e6d099128936 Mon Sep 17 00:00:00 2001 From: 4t145 Date: Thu, 29 Feb 2024 11:15:48 +0800 Subject: [PATCH 2/2] add status web api --- tardis/src/cluster/cluster_processor.rs | 43 ++++++++++++-- tardis/src/lib.rs | 3 +- tardis/src/web/web_server.rs | 2 +- tardis/src/web/web_server/status_api.rs | 76 +++++++++++++++++++++++++ tardis/tests/test_web_server.rs | 20 +++++-- 5 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 tardis/src/web/web_server/status_api.rs diff --git a/tardis/src/cluster/cluster_processor.rs b/tardis/src/cluster/cluster_processor.rs index c3470dca..32f060df 100644 --- a/tardis/src/cluster/cluster_processor.rs +++ b/tardis/src/cluster/cluster_processor.rs @@ -19,6 +19,7 @@ use crate::cluster::cluster_watch_by_cache; use crate::cluster::cluster_watch_by_k8s; use crate::config::config_dto::FrameworkConfig; use crate::tardis_static; +use crate::web::web_server::status_api::TardisStatus; use crate::web::web_server::TardisWebServer; use crate::web::ws_client::TardisWSClient; use crate::web::ws_processor::ws_insts_mapping_avatars; @@ -28,6 +29,7 @@ use async_trait::async_trait; pub const CLUSTER_NODE_WHOAMI: &str = "__cluster_node_who_am_i__"; pub const EVENT_PING: &str = "tardis/ping"; +pub const EVENT_STATUS: &str = "tardis/status"; pub const CLUSTER_MESSAGE_CACHE_SIZE: usize = 10000; pub const WHOAMI_TIMEOUT: Duration = Duration::from_secs(30); @@ -38,7 +40,7 @@ tardis_static! { pub async set local_node_id: String; pub async set responser_dispatcher: mpsc::Sender; pub(crate) cache_nodes: Arc>>; - subscribers: Arc>>>; + pub(crate) subscribers: Arc>>>; } /// clone the cache_nodes_info at current time @@ -161,6 +163,38 @@ impl TardisClusterSubscriber for EventPing { } } +pub(crate) struct EventStatus; +#[async_trait] + +impl TardisClusterSubscriber for EventStatus { + fn event_name(&self) -> Cow<'static, str> { + EVENT_STATUS.into() + } + async fn subscribe(&self, _message_req: TardisClusterMessageReq) -> TardisResult> { + Ok(Some(serde_json::to_value(TardisStatus::fetch().await).expect("spec always be a valid json value"))) + } +} + +impl EventStatus { + pub async fn get_by_id(cluster_id: &str) -> TardisResult { + if cluster_id == *local_node_id().await { + Ok(TardisStatus::fetch().await) + } else { + let resp = publish_event_one_response( + EventStatus.event_name(), + Default::default(), + ClusterEventTarget::Single(ClusterRemoteNodeKey::NodeId(cluster_id.to_string())), + None, + ) + .await?; + serde_json::from_value(resp.msg).map_err(|e| { + let error_info = format!("[Tardis.Cluster] [Client] receive message error: {e}"); + TardisError::wrap(&error_info, "-1-tardis-cluster-receive-message-error") + }) + } + } +} + pub async fn init_by_conf(conf: &FrameworkConfig, cluster_server: &TardisWebServer) -> TardisResult<()> { if let Some(cluster_config) = &conf.cluster { let web_server_config = conf.web_server.as_ref().expect("missing web server config"); @@ -199,6 +233,7 @@ async fn init_node(cluster_server: &TardisWebServer, access_addr: SocketAddr) -> subscribe(EventPing).await; #[cfg(feature = "web-server")] { + subscribe(EventStatus).await; subscribe(ws_insts_mapping_avatars().clone()).await; } @@ -286,9 +321,7 @@ pub async fn subscribe_boxed(subscriber: Box) { } pub async fn subscribe(subscriber: S) { - let event_name = subscriber.event_name(); - info!("[Tardis.Cluster] [Server] subscribe event {event_name}"); - subscribers().write().await.insert(event_name, Box::new(subscriber)); + subscribe_boxed(Box::new(subscriber)).await; } pub async fn unsubscribe(event_name: &str) { @@ -371,6 +404,8 @@ impl TardisClusterNode {} use std::hash::Hash; +use super::cluster_publish::publish_event_one_response; + #[derive(Debug, Clone)] struct ClusterAPI; diff --git a/tardis/src/lib.rs b/tardis/src/lib.rs index 4715a28b..de80e55f 100644 --- a/tardis/src/lib.rs +++ b/tardis/src/lib.rs @@ -497,9 +497,8 @@ impl TardisFuns { TardisFunsInst::new_with_db_conn(code.into(), lang) } - /// Clone the current config into [`TardisConfig`](TardisConfig), this may be used to reload config. - /// + /// pub fn clone_config() -> TardisConfig { let cs = TARDIS_INST.custom_config.read().iter().map(|(k, v)| (k.clone(), v.raw().clone())).collect::>(); let fw = TARDIS_INST.framework_config.get().as_ref().clone(); diff --git a/tardis/src/web/web_server.rs b/tardis/src/web/web_server.rs index d4525b06..a44706df 100644 --- a/tardis/src/web/web_server.rs +++ b/tardis/src/web/web_server.rs @@ -28,7 +28,7 @@ mod initializer; use initializer::*; mod module; pub use module::*; - +pub mod status_api; pub type BoxMiddleware<'a, T = BoxEndpoint<'a>> = Box + Send>; type ServerTaskInner = JoinHandle>; struct ServerTask { diff --git a/tardis/src/web/web_server/status_api.rs b/tardis/src/web/web_server/status_api.rs new file mode 100644 index 00000000..713f2cc1 --- /dev/null +++ b/tardis/src/web/web_server/status_api.rs @@ -0,0 +1,76 @@ +use std::collections::HashMap; + +use poem_openapi::{param::Query, Object}; +use serde::{Deserialize, Serialize}; + +use crate::web::web_resp::{TardisApiResult, TardisResp}; +#[derive(Debug, Clone)] +pub struct TardisStatusApi; +#[derive(Debug, Serialize, Deserialize, Object)] +pub struct TardisStatus { + pub version: String, + #[cfg(feature = "build-info")] + pub git_version: String, + #[cfg(feature = "cluster")] + pub cluster: TardisClusterStatus, + pub fw_config: serde_json::Value, + // support in the future + // pub cs_config: HashMap, +} + +impl TardisStatus { + pub async fn fetch() -> TardisStatus { + TardisStatus { + version: env!("CARGO_PKG_VERSION").to_string(), + #[cfg(feature = "build-info")] + git_version: crate::utils::build_info::git_version!().to_string(), + #[cfg(feature = "cluster")] + cluster: TardisClusterStatus::fetch().await, + fw_config: serde_json::to_value(crate::TardisFuns::fw_config().as_ref().clone()).unwrap_or_default(), + // support in the future + // cs_config: crate::TardisFuns::, + } + } +} + +#[cfg(feature = "cluster")] +#[derive(Debug, Serialize, Deserialize, Object)] +pub struct TardisClusterStatus { + pub cluster_id: String, + pub peer_nodes: HashMap, + pub subscribed: Vec, +} + +#[cfg(feature = "cluster")] +impl TardisClusterStatus { + pub async fn fetch() -> TardisClusterStatus { + TardisClusterStatus { + cluster_id: crate::cluster::cluster_processor::local_node_id().await.to_string(), + peer_nodes: crate::cluster::cluster_processor::cache_nodes().read().await.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect(), + subscribed: crate::cluster::cluster_processor::subscribers().read().await.iter().map(|(k, _)| k.to_string()).collect(), + } + } +} + +#[poem_openapi::OpenApi] +impl TardisStatusApi { + #[oai(path = "/status", method = "get")] + pub async fn status(&self, cluster_id: Query>) -> TardisApiResult { + let cluster_id = cluster_id.0; + if let Some(id) = cluster_id { + #[cfg(feature = "cluster")] + { + if id == *crate::cluster::cluster_processor::local_node_id().await { + return TardisResp::ok(TardisStatus::fetch().await); + } + let status = crate::cluster::cluster_processor::EventStatus::get_by_id(&id).await?; + return TardisResp::ok(status); + } + #[cfg(not(feature = "cluster"))] + { + return TardisResp::err(TardisError::internal_error("cluster features not enabled", "")); + } + } + TardisResp::ok(TardisStatus::fetch().await) + } +} diff --git a/tardis/tests/test_web_server.rs b/tardis/tests/test_web_server.rs index 359e627b..2a7b7c7b 100644 --- a/tardis/tests/test_web_server.rs +++ b/tardis/tests/test_web_server.rs @@ -11,6 +11,7 @@ use poem::endpoint::BoxEndpoint; use poem::http::Method; use poem::{IntoResponse, Middleware, Response}; use serde_json::json; +use tardis::web::web_server::status_api::{TardisStatus, TardisStatusApi}; use tardis::web::web_server::WebServerModule; use testcontainers::clients; use tokio::time::sleep; @@ -98,7 +99,7 @@ async fn test_web_server() -> TardisResult<()> { let redis_container = TardisTestContainer::redis_custom(&docker); let redis_port = redis_container.get_host_port_ipv4(6379); let redis_url = format!("redis://127.0.0.1:{redis_port}/0"); - + tardis::cluster::cluster_processor::set_local_node_id("test".into()); start_serv(web_url, &redis_url).await?; sleep(Duration::from_millis(500)).await; @@ -132,9 +133,12 @@ async fn start_serv(web_url: &str, redis_url: &str) -> TardisResult<()> { .build(), ) .cache(CacheModuleConfig::builder().url(redis_url.parse().expect("invalid redis url")).build()) - .log(LogConfig::builder().directives([ - Directive::from_str("poem=debug").expect("invalid directives") - ]).level(Directive::from_str("info").expect("invalid directives")).build()) + .log( + LogConfig::builder() + .directives([Directive::from_str("poem=debug").expect("invalid directives")]) + .level(Directive::from_str("info").expect("invalid directives")) + .build(), + ) .build(); TardisFuns::init_conf(TardisConfig { cs: Default::default(), @@ -142,6 +146,8 @@ async fn start_serv(web_url: &str, redis_url: &str) -> TardisResult<()> { }) .await?; TardisFuns::web_server() + .add_module("_tardis", TardisStatusApi) + .await .add_module("todo", TodosApi) .await .add_module("other", OtherApi) @@ -155,6 +161,12 @@ async fn start_serv(web_url: &str, redis_url: &str) -> TardisResult<()> { } async fn test_basic(url: &str) -> TardisResult<()> { + // Status + let response = TardisFuns::web_client().get::>(format!("{url}/_tardis/status").as_str(), None).await?; + assert_eq!(response.code, 200); + assert_eq!(response.body.as_ref().unwrap().code, TARDIS_RESULT_SUCCESS_CODE); + tracing::info!("status: {:?}", response.body); + // Normal let response = TardisFuns::web_client().get::>(format!("{url}/todo/todos/1").as_str(), None).await?; assert_eq!(response.code, 200);