From 168561b720ab4d7df40f28a820cd007c0e22fc8e Mon Sep 17 00:00:00 2001 From: owlot <95369289+owlot@users.noreply.github.com> Date: Tue, 26 Sep 2023 11:06:27 +0200 Subject: [PATCH] chore: debug fixes and version bumps --- Cargo.lock | 81 ++++++++++++++++------ client-grpc/Cargo.toml | 2 +- client-grpc/examples/grpc.rs | 14 ++-- client-grpc/src/client.rs | 92 +++++++++++++++++++++++++ client-grpc/src/lib.rs | 97 ++------------------------- client-grpc/src/prelude.rs | 7 ++ client-grpc/src/service.rs | 15 ++--- client-grpc/tests/integration_test.rs | 25 ++----- client-rest/Cargo.toml | 2 +- log4rs.yaml | 6 +- server/Cargo.toml | 17 +++-- server/src/config.rs | 17 +++-- server/src/grpc/client.rs | 13 ++-- server/src/grpc/server.rs | 16 ++--- server/src/lib.rs | 81 +++++++++++++++++----- server/src/main.rs | 11 +-- server/src/rest/api.rs | 21 +++--- server/src/rest/mod.rs | 9 ++- server/src/test_util.rs | 2 +- server/tests/integration_test.rs | 2 +- 20 files changed, 312 insertions(+), 218 deletions(-) create mode 100644 client-grpc/src/client.rs create mode 100644 client-grpc/src/prelude.rs diff --git a/Cargo.lock b/Cargo.lock index 0da0b0c..ad3f6aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -124,12 +124,33 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "arrow-macros-core" +version = "0.2.0" +source = "git+https://github.com/Arrow-air/lib-common.git?tag=v0.2.0#ecae9794fb2220aa03fdc04329bda32ca8441056" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "arrow-macros-derive" version = "0.1.1-develop.2" source = "git+https://github.com/Arrow-air/lib-common.git?tag=v0.1.1-develop.2#c7e0fc4918d3346a13ab84e2d4fc16d430a60c59" dependencies = [ - "arrow-macros-core", + "arrow-macros-core 0.1.1-develop.2", + "proc-macro-error", + "proc-macro2", +] + +[[package]] +name = "arrow-macros-derive" +version = "0.2.0" +source = "git+https://github.com/Arrow-air/lib-common.git?tag=v0.2.0#ecae9794fb2220aa03fdc04329bda32ca8441056" +dependencies = [ + "arrow-macros-core 0.2.0", "proc-macro-error", "proc-macro2", ] @@ -327,9 +348,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.7" +version = "4.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +checksum = "fb690e81c7840c0d7aade59f242ea3b41b9bc27bcd5997890e7702ae4b32e487" dependencies = [ "clap_builder", "clap_derive", @@ -338,22 +359,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.7" +version = "4.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +checksum = "5ed2e96bc16d8d740f6f48d663eddf4b8a0983e79210fd55479b7bcd0a69860e" dependencies = [ "anstream", "anstyle", - "bitflags 1.3.2", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", @@ -363,9 +383,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "colorchoice" @@ -1088,7 +1108,23 @@ name = "lib-common" version = "0.1.1-develop.2" source = "git+https://github.com/Arrow-air/lib-common.git?tag=v0.1.1-develop.2#c7e0fc4918d3346a13ab84e2d4fc16d430a60c59" dependencies = [ - "arrow-macros-derive", + "arrow-macros-derive 0.1.1-develop.2", + "cargo-husky", + "chrono", + "futures", + "log", + "prost", + "prost-types", + "tonic", + "trybuild", +] + +[[package]] +name = "lib-common" +version = "0.2.0" +source = "git+https://github.com/Arrow-air/lib-common.git?tag=v0.2.0#ecae9794fb2220aa03fdc04329bda32ca8441056" +dependencies = [ + "arrow-macros-derive 0.2.0", "cargo-husky", "chrono", "futures", @@ -2173,8 +2209,8 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "svc-storage" -version = "0.10.1-develop.18" -source = "git+https://github.com/Arrow-air/svc-storage?tag=v0.10.1-develop.18#e98bd03cea50447e09e94832b6f39664a9957cbe" +version = "0.11.0" +source = "git+https://github.com/Arrow-air/svc-storage?tag=v0.11.0#e58dcdc9587a7e5cde605f68de94918e4d0fbd71" dependencies = [ "anyhow", "byteorder", @@ -2183,6 +2219,7 @@ dependencies = [ "cfg-if", "chrono", "clap", + "clap_lex", "config", "deadpool", "deadpool-postgres", @@ -2192,7 +2229,7 @@ dependencies = [ "geo-types", "hyper", "lazy_static", - "lib-common", + "lib-common 0.2.0", "log", "log4rs", "native-tls", @@ -2200,7 +2237,6 @@ dependencies = [ "num-traits", "once_cell", "openssl", - "ordered-float 3.7.0", "paste", "postgis", "postgres-native-tls", @@ -2224,15 +2260,15 @@ dependencies = [ [[package]] name = "svc-storage-client-grpc" -version = "0.10.1-develop.18" -source = "git+https://github.com/Arrow-air/svc-storage?tag=v0.10.1-develop.18#e98bd03cea50447e09e94832b6f39664a9957cbe" +version = "0.11.0" +source = "git+https://github.com/Arrow-air/svc-storage?tag=v0.11.0#e58dcdc9587a7e5cde605f68de94918e4d0fbd71" dependencies = [ "anyhow", "cfg-if", "futures", "geo-types", "lazy_static", - "lib-common", + "lib-common 0.2.0", "log", "num-derive", "num-traits", @@ -2261,10 +2297,11 @@ dependencies = [ "cargo-husky", "chrono", "clap", + "clap_lex", "config", "dotenv", "hyper", - "lib-common", + "lib-common 0.2.0", "log", "log4rs", "logtest", @@ -2291,7 +2328,7 @@ name = "svc-template-rust-client-grpc" version = "0.2.0-develop.4" source = "git+https://github.com/Arrow-air/svc-template-rust.git?tag=v0.2.0-develop.4#8056706bc214158644d80fa8a8662a01e0c5db5f" dependencies = [ - "lib-common", + "lib-common 0.1.1-develop.2", "log", "prost", "prost-types", @@ -2303,7 +2340,7 @@ name = "svc-template-rust-client-grpc" version = "0.2.0-develop.6" dependencies = [ "cfg-if", - "lib-common", + "lib-common 0.2.0", "log", "logtest", "prost", @@ -2321,7 +2358,7 @@ version = "0.2.0-develop.6" dependencies = [ "chrono", "hyper", - "lib-common", + "lib-common 0.2.0", "serde", "serde_json", "tokio", diff --git a/client-grpc/Cargo.toml b/client-grpc/Cargo.toml index 453c4c6..f1b04e6 100644 --- a/client-grpc/Cargo.toml +++ b/client-grpc/Cargo.toml @@ -37,7 +37,7 @@ tower = { version = "0.4", optional = true } [dependencies.lib-common] features = ["grpc"] git = "https://github.com/Arrow-air/lib-common.git" -tag = "v0.1.1-develop.2" +tag = "v0.2.0" [dependencies.tokio] features = ["macros", "rt-multi-thread"] diff --git a/client-grpc/examples/grpc.rs b/client-grpc/examples/grpc.rs index 431e407..e5910a5 100644 --- a/client-grpc/examples/grpc.rs +++ b/client-grpc/examples/grpc.rs @@ -1,24 +1,20 @@ //! gRPC client implementation use lib_common::grpc::get_endpoint_from_env; -use svc_template_rust_client_grpc::client::{ReadyRequest, RpcServiceClient}; -use svc_template_rust_client_grpc::service::Client as ServiceClient; -use svc_template_rust_client_grpc::{Client, GrpcClient}; -use tonic::transport::Channel; +use svc_template_rust_client_grpc::prelude::*; /// Example svc-template-rust-client-grpc #[tokio::main] async fn main() -> Result<(), Box> { let (host, port) = get_endpoint_from_env("SERVER_HOSTNAME", "SERVER_PORT_GRPC"); - let connection = - GrpcClient::>::new_client(&host, port, "template_rust"); - println!("Connection created"); + let client = TemplateRustClient::new_client(&host, port, "template_rust"); + println!("Client created."); println!( "NOTE: Ensure the server is running on {} or this example will fail.", - connection.get_address() + client.get_address() ); - let response = connection.is_ready(ReadyRequest {}).await?; + let response = client.is_ready(template_rust::ReadyRequest {}).await?; println!("RESPONSE={:?}", response.into_inner()); diff --git a/client-grpc/src/client.rs b/client-grpc/src/client.rs new file mode 100644 index 0000000..4297708 --- /dev/null +++ b/client-grpc/src/client.rs @@ -0,0 +1,92 @@ +//! Client Library: Client Functions, Structs, Traits +#![allow(unused_qualifications)] +include!("grpc.rs"); + +use super::*; + +#[cfg(not(feature = "stub_client"))] +use lib_common::grpc::ClientConnect; +use lib_common::grpc::{Client, GrpcClient}; +use rpc_service_client::RpcServiceClient; +/// GrpcClient implementation of the RpcServiceClient +pub type TemplateRustClient = GrpcClient>; + +cfg_if::cfg_if! { + if #[cfg(feature = "stub_backends")] { + use svc_template_rust::grpc::server::{RpcServiceServer, ServerImpl}; + lib_common::grpc_mock_client!(RpcServiceClient, RpcServiceServer, ServerImpl); + super::log_macros!("grpc", "app::client::mock::template_rust"); + } else { + lib_common::grpc_client!(RpcServiceClient); + super::log_macros!("grpc", "app::client::template_rust"); + } +} + +#[cfg(not(feature = "stub_client"))] +#[async_trait] +impl crate::service::Client> for TemplateRustClient { + type ReadyRequest = ReadyRequest; + type ReadyResponse = ReadyResponse; + + async fn is_ready( + &self, + request: Self::ReadyRequest, + ) -> Result, tonic::Status> { + grpc_info!("(is_ready) {} client.", self.get_name()); + grpc_debug!("(is_ready) request: {:?}", request); + self.get_client().await?.is_ready(request).await + } +} + +#[cfg(feature = "stub_client")] +#[async_trait] +impl crate::service::Client> for TemplateRustClient { + type ReadyRequest = ReadyRequest; + type ReadyResponse = ReadyResponse; + + async fn is_ready( + &self, + request: Self::ReadyRequest, + ) -> Result, tonic::Status> { + grpc_warn!("(is_ready MOCK) {} client.", self.get_name()); + grpc_debug!("(is_ready MOCK) request: {:?}", request); + Ok(tonic::Response::new(ReadyResponse { ready: true })) + } +} + +#[cfg(test)] +mod tests { + use crate::service::Client as ServiceClient; + + use super::*; + + #[tokio::test] + #[cfg(not(feature = "stub_client"))] + async fn test_client_connect() { + let name = "template_rust"; + let (server_host, server_port) = + lib_common::grpc::get_endpoint_from_env("GRPC_HOST", "GRPC_PORT"); + + let client: TemplateRustClient = GrpcClient::new_client(&server_host, server_port, name); + assert_eq!(client.get_name(), name); + + let connection = client.get_client().await; + println!("{:?}", connection); + assert!(connection.is_ok()); + } + + #[tokio::test] + async fn test_client_is_ready_request() { + let name = "template_rust"; + let (server_host, server_port) = + lib_common::grpc::get_endpoint_from_env("GRPC_HOST", "GRPC_PORT"); + + let client: TemplateRustClient = GrpcClient::new_client(&server_host, server_port, name); + assert_eq!(client.get_name(), name); + + let result = client.is_ready(ReadyRequest {}).await; + println!("{:?}", result); + assert!(result.is_ok()); + assert_eq!(result.unwrap().into_inner().ready, true); + } +} diff --git a/client-grpc/src/lib.rs b/client-grpc/src/lib.rs index 320e3e1..036530e 100644 --- a/client-grpc/src/lib.rs +++ b/client-grpc/src/lib.rs @@ -1,100 +1,11 @@ #![doc = include_str!("../README.md")] +pub mod client; +pub mod prelude; pub mod service; -pub use client::*; -pub use lib_common::grpc::{Client, ClientConnect, GrpcClient}; + +//use client::*; use lib_common::log_macros; use tonic::async_trait; use tonic::transport::Channel; - -pub mod client { - //! Client Library: Client Functions, Structs, Traits - #![allow(unused_qualifications)] - include!("grpc.rs"); - - use super::*; - - pub use rpc_service_client::RpcServiceClient; - cfg_if::cfg_if! { - if #[cfg(feature = "stub_backends")] { - use svc_template_rust::grpc::server::{RpcServiceServer, ServerImpl}; - lib_common::grpc_mock_client!(RpcServiceClient, RpcServiceServer, ServerImpl); - super::log_macros!("grpc", "app::client::mock::template_rust"); - } else { - lib_common::grpc_client!(RpcServiceClient); - super::log_macros!("grpc", "app::client::template_rust"); - } - } -} - -#[cfg(not(feature = "stub_client"))] -#[async_trait] -impl crate::service::Client> for GrpcClient> { - type ReadyRequest = ReadyRequest; - type ReadyResponse = ReadyResponse; - - async fn is_ready( - &self, - request: Self::ReadyRequest, - ) -> Result, tonic::Status> { - grpc_info!("(is_ready) {} client.", self.get_name()); - grpc_debug!("(is_ready) request: {:?}", request); - self.get_client().await?.is_ready(request).await - } -} -#[cfg(feature = "stub_client")] -#[async_trait] -impl crate::service::Client> for GrpcClient> { - type ReadyRequest = ReadyRequest; - type ReadyResponse = ReadyResponse; - - async fn is_ready( - &self, - request: Self::ReadyRequest, - ) -> Result, tonic::Status> { - grpc_warn!("(is_ready MOCK) {} client.", self.get_name()); - grpc_debug!("(is_ready MOCK) request: {:?}", request); - Ok(tonic::Response::new(ReadyResponse { ready: true })) - } -} - -#[cfg(test)] -mod tests { - use crate::service::Client as ServiceClient; - - use super::*; - use tonic::transport::Channel; - - #[tokio::test] - #[cfg(not(feature = "stub_client"))] - async fn test_client_connect() { - let name = "template_rust"; - let (server_host, server_port) = - lib_common::grpc::get_endpoint_from_env("GRPC_HOST", "GRPC_PORT"); - - let client: GrpcClient> = - GrpcClient::new_client(&server_host, server_port, name); - assert_eq!(client.get_name(), name); - - let connection = client.get_client().await; - println!("{:?}", connection); - assert!(connection.is_ok()); - } - - #[tokio::test] - async fn test_client_is_ready_request() { - let name = "template_rust"; - let (server_host, server_port) = - lib_common::grpc::get_endpoint_from_env("GRPC_HOST", "GRPC_PORT"); - - let client: GrpcClient> = - GrpcClient::new_client(&server_host, server_port, name); - assert_eq!(client.get_name(), name); - - let result = client.is_ready(ReadyRequest {}).await; - println!("{:?}", result); - assert!(result.is_ok()); - assert_eq!(result.unwrap().into_inner().ready, true); - } -} diff --git a/client-grpc/src/prelude.rs b/client-grpc/src/prelude.rs new file mode 100644 index 0000000..2502ff4 --- /dev/null +++ b/client-grpc/src/prelude.rs @@ -0,0 +1,7 @@ +//! Re-export of used objects + +pub use super::client as template_rust; +pub use super::service::Client as TemplateRustServiceClient; +pub use template_rust::TemplateRustClient; + +pub use lib_common::grpc::Client; diff --git a/client-grpc/src/service.rs b/client-grpc/src/service.rs index bf6166d..fd00d62 100644 --- a/client-grpc/src/service.rs +++ b/client-grpc/src/service.rs @@ -1,4 +1,5 @@ //! Client Library: Client Functions, Structs, Traits + /// gRPC object traits to provide wrappers for grpc functions #[tonic::async_trait] pub trait Client @@ -16,22 +17,18 @@ where /// /// # Errors /// - /// Returns [`tonic::Status`] with [`Code::Unknown`](tonic::Code::Unknown) if - /// the server is not ready. + /// Returns [`tonic::Status`] with [`tonic::Code::Unknown`] if the server is not ready. /// /// # Examples /// ``` /// use lib_common::grpc::get_endpoint_from_env; - /// use svc_template_rust_client_grpc::client::{ReadyRequest, RpcServiceClient}; - /// use svc_template_rust_client_grpc::{Client, GrpcClient}; - /// use svc_template_rust_client_grpc::service::Client as ServiceClient; - /// use tonic::transport::Channel; + /// use svc_template_rust_client_grpc::prelude::*; /// /// async fn example () -> Result<(), Box> { /// let (host, port) = get_endpoint_from_env("SERVER_HOSTNAME", "SERVER_PORT_GRPC"); - /// let connection = GrpcClient::>::new_client(&host, port, "template_rust"); - /// let response = connection - /// .is_ready(ReadyRequest {}) + /// let client = TemplateRustClient::new_client(&host, port, "template_rust"); + /// let response = client + /// .is_ready(template_rust::ReadyRequest {}) /// .await?; /// println!("RESPONSE={:?}", response.into_inner()); /// Ok(()) diff --git a/client-grpc/tests/integration_test.rs b/client-grpc/tests/integration_test.rs index 68e64a8..516f463 100644 --- a/client-grpc/tests/integration_test.rs +++ b/client-grpc/tests/integration_test.rs @@ -1,20 +1,4 @@ //! Integration Tests -use lib_common::grpc::get_endpoint_from_env; -use svc_template_rust_client_grpc::service::Client as ServiceClient; -use svc_template_rust_client_grpc::*; -use tokio::sync::OnceCell; -use tonic::transport::Channel; - -pub(crate) static CLIENT: OnceCell>> = OnceCell::const_new(); - -pub async fn get_client() -> &'static GrpcClient> { - CLIENT - .get_or_init(|| async move { - let (host, port) = get_endpoint_from_env("SERVER_HOSTNAME", "SERVER_PORT_GRPC"); - GrpcClient::>::new_client(&host, port, "template_rust") - }) - .await -} fn get_log_string(function: &str, name: &str) -> String { #[cfg(feature = "stub_client")] @@ -34,15 +18,20 @@ fn get_log_string(function: &str, name: &str) -> String { async fn test_client_requests_and_logs() { use logtest::Logger; + use svc_template_rust_client_grpc::prelude::*; + let name = "template_rust"; - let client = get_client().await; + let (server_host, server_port) = + lib_common::grpc::get_endpoint_from_env("GRPC_HOST", "GRPC_PORT"); + + let client = TemplateRustClient::new_client(&server_host, server_port, name); // Start the logger. let mut logger = Logger::start(); //test_is_ready_request_logs { - let result = client.is_ready(ReadyRequest {}).await; + let result = client.is_ready(template_rust::ReadyRequest {}).await; println!("{:?}", result); assert!(result.is_ok()); diff --git a/client-rest/Cargo.toml b/client-rest/Cargo.toml index f7a7a4e..9571138 100644 --- a/client-rest/Cargo.toml +++ b/client-rest/Cargo.toml @@ -28,7 +28,7 @@ uuid = { version = "1.3.0", features = ["v4"] } [dev-dependencies.lib-common] features = ["grpc"] git = "https://github.com/Arrow-air/lib-common.git" -tag = "v0.1.1-develop.2" +tag = "v0.2.0" [[example]] name = "rest" diff --git a/log4rs.yaml b/log4rs.yaml index 0f64754..58472ee 100644 --- a/log4rs.yaml +++ b/log4rs.yaml @@ -4,7 +4,7 @@ appenders: kind: console encoder: # https://medium.com/nikmas-group-rust/advanced-logging-in-rust-with-log4rs-2d712bb322de - pattern: "{d(%Y-%m-%d %H:%M:%S)} | {({l}):5.5} | {f}:{L} — {m}{n}" + pattern: "{d(%Y-%m-%d %H:%M:%S)} | {I} | {h({l}):5.5} | {f}:{L} | {m}{n}" grpc_requests: kind: rolling_file path: "logs/grpc_requests.log" @@ -62,11 +62,11 @@ loggers: level: info appenders: - rest_requests - test::unit: + test::ut: level: info appenders: - tests - test::integration: + test::it: level: info appenders: - tests diff --git a/server/Cargo.toml b/server/Cargo.toml index 7059880..67723c3 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -30,15 +30,18 @@ stub_server = ["test_util"] stub_client = ["stub_backends"] [dependencies] -anyhow = "1.0" -axum = "0.6" -cargo-husky = "1" -chrono = { version = "0.4", features = ["serde"] } -clap = { version = "4.0", features = ["derive"] } +anyhow = "1.0" +axum = "0.6" +cargo-husky = "1" +chrono = { version = "0.4", features = ["serde"] } +# pin clap to 4.3 for now, since 4.4 requires rustc 1.70.0 or newer. +clap = { version = "=4.3.24", features = ["derive"] } +# pin clap_lex to 0.5.0 for now, since 0.5.1 requires rustc 1.70.0 or newer. +clap_lex = "=0.5.0" config = "0.13" dotenv = "0.15" hyper = "0.14" -lib-common = { git = "https://github.com/Arrow-air/lib-common.git", tag = "v0.1.1-develop.2" } +lib-common = { git = "https://github.com/Arrow-air/lib-common.git", tag = "v0.2.0" } log = "0.4" openssl = "0.10" prost = "0.11" @@ -62,7 +65,7 @@ tag = "v0.2.0-develop.4" [dependencies.svc-storage-client-grpc] features = ["adsb"] git = "https://github.com/Arrow-air/svc-storage" -tag = "v0.10.1-develop.18" +tag = "v0.11.0" # ======================================================== [dependencies.log4rs] diff --git a/server/src/config.rs b/server/src/config.rs index b2a620c..595ae6d 100644 --- a/server/src/config.rs +++ b/server/src/config.rs @@ -81,10 +81,13 @@ impl Config { #[cfg(test)] mod tests { - use crate::{init_logger, Config}; + use super::Config; + + #[tokio::test] + async fn test_config_from_default() { + crate::get_log_handle().await; + ut_info!("(test_config_from_default) Start."); - #[test] - fn test_config_from_default() { let config = Config::default(); assert_eq!(config.docker_port_grpc, 50051); @@ -98,12 +101,14 @@ mod tests { config.rest_cors_allowed_origin, String::from("http://localhost:3000") ); + + ut_info!("(test_config_from_default) Success."); } #[tokio::test] async fn test_config_from_env() { - // Make sure logger is initialized for tests before we mess with our env vars - init_logger(&Config::try_from_env().unwrap_or_default()); + crate::get_log_handle().await; + ut_info!("(test_config_from_env) Start."); std::env::set_var("DOCKER_PORT_GRPC", "6789"); std::env::set_var("DOCKER_PORT_REST", "9876"); @@ -132,5 +137,7 @@ mod tests { config.rest_cors_allowed_origin, String::from("https://allowed.origin.host:443") ); + + ut_info!("(test_config_from_env) Success."); } } diff --git a/server/src/grpc/client.rs b/server/src/grpc/client.rs index d35f022..080b125 100644 --- a/server/src/grpc/client.rs +++ b/server/src/grpc/client.rs @@ -40,20 +40,19 @@ impl GrpcClients { #[cfg(test)] mod tests { use super::*; - use crate::{init_logger, Config}; - - use svc_storage_client_grpc::Client; + use lib_common::grpc::Client; #[tokio::test] async fn test_grpc_clients_default() { - init_logger(&Config::try_from_env().unwrap_or_default()); - unit_test_info!("Testing GrpcClients default function."); + crate::get_log_handle().await; + ut_info!("(test_grpc_clients_default) Start."); let config = crate::Config::default(); let clients = GrpcClients::default(config); let adsb = clients.storage.adsb; - println!("{:?}", adsb); + ut_debug!("(test_grpc_clients_default) adsb: {:?}", adsb); assert_eq!(adsb.get_name(), "adsb"); - unit_test_info!("Test success."); + + ut_info!("(test_grpc_clients_default) Success."); } } diff --git a/server/src/grpc/server.rs b/server/src/grpc/server.rs index 2d2deee..d058810 100644 --- a/server/src/grpc/server.rs +++ b/server/src/grpc/server.rs @@ -29,7 +29,7 @@ impl RpcService for ServerImpl { request: Request, ) -> Result, Status> { grpc_info!("(is_ready) template_rust server."); - grpc_debug!("(is_ready) request: {:?}", request); + grpc_debug!("(is_ready) [{:?}].", request); let response = ReadyResponse { ready: true }; Ok(Response::new(response)) } @@ -68,7 +68,7 @@ pub async fn grpc_server(config: Config, shutdown_rx: Option grpc_info!("(grpc_server) gRPC server running at: {}.", full_grpc_addr), + Ok(_) => grpc_info!("(grpc_server) gRPC server running at: {}", full_grpc_addr), Err(e) => { grpc_error!("(grpc_server) Could not start gRPC server: {}", e); } @@ -92,7 +92,7 @@ impl RpcService for ServerImpl { request: Request, ) -> Result, Status> { grpc_warn!("(is_ready MOCK) template_rust server."); - grpc_debug!("(is_ready MOCK) request: {:?}", request); + grpc_debug!("(is_ready MOCK) [{:?}].", request); let response = ReadyResponse { ready: true }; Ok(Response::new(response)) } @@ -101,18 +101,18 @@ impl RpcService for ServerImpl { #[cfg(test)] mod tests { use super::*; - use crate::{init_logger, Config}; #[tokio::test] async fn test_grpc_server_is_ready() { - init_logger(&Config::try_from_env().unwrap_or_default()); - unit_test_info!("Testing is_ready service."); + crate::get_log_handle().await; + ut_info!("(test_grpc_server_is_ready) Start."); let imp = ServerImpl::default(); let result = imp.is_ready(Request::new(ReadyRequest {})).await; assert!(result.is_ok()); let result: ReadyResponse = result.unwrap().into_inner(); assert_eq!(result.ready, true); - unit_test_info!("Test success."); + + ut_info!("(test_grpc_server_is_ready) Success."); } } diff --git a/server/src/lib.rs b/server/src/lib.rs index edea71e..edb8376 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,11 +1,16 @@ #![doc = include_str!("../README.md")] +use tokio::sync::OnceCell; + #[cfg(test)] #[macro_use] pub mod test_util; -mod config; +pub mod config; pub mod grpc; + +pub use crate::config::Config; + // -------------------------------------------------- // START REST SECTION // This section should be removed if there is no REST interface @@ -26,21 +31,47 @@ pub struct Cli { // END REST SECTION // -------------------------------------------------- -pub use crate::config::Config; -use std::sync::Once; - -static INIT_LOGGER: Once = Once::new(); -/// Initialize the logger with provided configuration -pub fn init_logger(config: &Config) { - INIT_LOGGER.call_once(|| { - let log_cfg: &str = config.log_config.as_str(); - if let Err(e) = log4rs::init_file(log_cfg, Default::default()) { - panic!( - "(logger) could not parse log config {} found in config {:?}: {}.", - log_cfg, config, e - ); +/// Initialized log4rs handle +pub static LOG_HANDLE: OnceCell> = OnceCell::const_new(); +pub(crate) async fn get_log_handle() -> Option { + LOG_HANDLE + .get_or_init(|| async move { + // Set up basic logger to make sure we can write to stdout + let stdout = log4rs::append::console::ConsoleAppender::builder() + .encoder(Box::new(log4rs::encode::pattern::PatternEncoder::new( + "{d(%Y-%m-%d %H:%M:%S)} | {I} | {h({l}):5.5} | {f}:{L} | {m}{n}", + ))) + .build(); + match log4rs::config::Config::builder() + .appender(log4rs::config::Appender::builder().build("stdout", Box::new(stdout))) + .build( + log4rs::config::Root::builder() + .appender("stdout") + .build(log::LevelFilter::Debug), + ) { + Ok(config) => log4rs::init_config(config).ok(), + Err(_) => None, + } + }) + .await + .to_owned() +} + +/// Initialize a log4rs logger with provided configuration file path +pub async fn load_logger_config_from_file(config_file: &str) -> Result<(), String> { + let log_handle = get_log_handle() + .await + .ok_or("(load_logger_config_from_file) Could not get the log handle.")?; + match log4rs::config::load_config_file(config_file, Default::default()) { + Ok(config) => { + log_handle.set_config(config); + Ok(()) } - }); + Err(e) => Err(format!( + "(logger) Could not parse log config file [{}]: {}.", + config_file, e, + )), + } } /// Tokio signal handler that will wait for a user to press CTRL+C. @@ -103,3 +134,23 @@ pub async fn shutdown_signal( log::warn!("(shutdown_signal) server shutdown for [{}]", server); } + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_load_logger_config_from_file() { + crate::get_log_handle().await; + ut_info!("(test_config_from_env) Start."); + + let result = load_logger_config_from_file("/usr/src/app/log4rs.yaml").await; + ut_debug!("(test_config_from_env) {:?}", result); + assert!(result.is_ok()); + + // This message should be written to file + ut_error!("(test_config_from_env) Testing log config from file. This should be written to the tests.log file."); + + ut_info!("(test_config_from_env) Success."); + } +} diff --git a/server/src/main.rs b/server/src/main.rs index b6324f6..e6e540e 100755 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -7,13 +7,14 @@ use svc_template_rust::*; #[tokio::main] #[cfg(not(tarpaulin_include))] async fn main() -> Result<(), Box> { - println!("(svc-template-rust) server startup."); - // Will use default config settings if no environment vars are found. let config = Config::try_from_env().unwrap_or_default(); - init_logger(&config); + // Try to load log configuration from the provided log file. + // Will default to stdout debug logging if the file can not be loaded. + load_logger_config_from_file(config.log_config.as_str()).await?; + info!("(main) Server startup."); // -------------------------------------------------- // START REST SECTION // This section should be removed if there is no REST interface @@ -34,10 +35,10 @@ async fn main() -> Result<(), Box> { tokio::spawn(grpc::server::grpc_server(config, None)).await?; + info!("(main) Server shutdown."); + // Make sure all log message are written/ displayed before shutdown log::logger().flush(); - info!("(svc-template-rust) server shutdown."); - Ok(()) } diff --git a/server/src/rest/api.rs b/server/src/rest/api.rs index 7b12fd9..e8affdf 100644 --- a/server/src/rest/api.rs +++ b/server/src/rest/api.rs @@ -6,16 +6,15 @@ pub mod rest_types { pub use rest_types::*; +use crate::grpc::client::GrpcClients; use axum::{extract::Extension, Json}; use hyper::StatusCode; -use svc_storage_client_grpc::*; - -use crate::grpc::client::GrpcClients; +use lib_common::grpc::ClientConnect; // gRPC client types -// use svc_scheduler_client_grpc::grpc::{ -// ConfirmItineraryRequest, Id, Itinerary as SchedulerItinerary, QueryFlightPlan, -// }; +// use svc_storage_client_grpc::prelude::*; +// use svc_scheduler_client_grpc::prelude::*; +// ... /// Provides a way to tell a caller if the service is healthy. /// Checks dependencies, making sure all connections can be made. @@ -128,15 +127,14 @@ pub async fn example( #[cfg(test)] mod tests { use super::*; - use crate::{init_logger, Config}; #[tokio::test] async fn test_health_check_success() { - let config = Config::try_from_env().unwrap_or_default(); - init_logger(&config); - unit_test_info!("Testing health_check service."); + crate::get_log_handle().await; + ut_info!("(test_health_check_success) Start."); // Mock the GrpcClients extension + let config = crate::Config::try_from_env().unwrap_or_default(); let grpc_clients = GrpcClients::default(config); // Replace with your own mock implementation // Call the health_check function @@ -145,6 +143,7 @@ mod tests { // Assert the expected result println!("{:?}", result); assert!(result.is_ok()); - unit_test_info!("Test success."); + + ut_info!("(test_health_check_success) Success."); } } diff --git a/server/src/rest/mod.rs b/server/src/rest/mod.rs index 287fc4f..cdbd16a 100644 --- a/server/src/rest/mod.rs +++ b/server/src/rest/mod.rs @@ -39,8 +39,13 @@ pub fn generate_openapi_spec(target: &str) -> Result<(), Box String { #[cfg(feature = "stub_server")]