diff --git a/kanin/Cargo.toml b/kanin/Cargo.toml index 01d071f..02c932c 100644 --- a/kanin/Cargo.toml +++ b/kanin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kanin" -version = "0.25.0" +version = "0.26.0" edition = "2021" authors = ["Victor Nordam Suadicani "] description = "An RPC microservice framework for AMQP, protobuf and Rust built on lapin (https://github.com/amqp-rs/lapin)." diff --git a/kanin/src/extract.rs b/kanin/src/extract.rs index 97ab958..f8c5f1a 100644 --- a/kanin/src/extract.rs +++ b/kanin/src/extract.rs @@ -1,5 +1,6 @@ //! Interface for types that can extract themselves from requests. +mod app_id; mod message; mod req_id; mod state; @@ -11,6 +12,7 @@ use lapin::{acker::Acker, message::Delivery, Channel}; use crate::{error::HandlerError, Request}; +pub use app_id::AppId; pub use message::Msg; pub use req_id::ReqId; pub use state::State; diff --git a/kanin/src/extract/app_id.rs b/kanin/src/extract/app_id.rs new file mode 100644 index 0000000..0b4fc7d --- /dev/null +++ b/kanin/src/extract/app_id.rs @@ -0,0 +1,22 @@ +//! App IDs defined in the request. + +use std::convert::Infallible; + +use async_trait::async_trait; + +use crate::{Extract, Request}; + +/// App ID extracted from the properties of the incoming request. Notice that this is already +/// logged as part of handling the request. +#[derive(Debug, Clone)] +pub struct AppId(pub Option); + +#[async_trait] +impl Extract for AppId { + type Error = Infallible; + + async fn extract(req: &mut Request) -> Result { + let app_id = req.app_id().map(|app_id| app_id.to_string()); + Ok(Self(app_id)) + } +} diff --git a/kanin/src/tests/send_recv.rs b/kanin/src/tests/send_recv.rs index 2385edb..5110f0c 100644 --- a/kanin/src/tests/send_recv.rs +++ b/kanin/src/tests/send_recv.rs @@ -13,7 +13,7 @@ use tracing::info; use crate::{ error::FromError, - extract::{ReqId, State}, + extract::{AppId, ReqId, State}, tests::init_logging, App, Extract, HandlerError, Request, Respond, }; @@ -80,6 +80,12 @@ async fn handler_req_id(req_id: ReqId) -> MyResponse { MyResponse("handler_req_id".into()) } +async fn handler_app_id(AppId(app_id): AppId) -> MyResponse { + assert_eq!(app_id.unwrap(), "my_app_id"); + SYNC.get().unwrap().send(()).await.unwrap(); + MyResponse("handler_app_id".into()) +} + async fn handler_two_extractors(_channel: Channel, _delivery: Delivery) -> MyResponse { SYNC.get().unwrap().send(()).await.unwrap(); MyResponse("handler_two_extractors".into()) @@ -121,6 +127,7 @@ async fn it_receives_various_messages_and_works_as_expected() { .handler("handler_channel", handler_channel) .handler("handler_delivery", handler_delivery) .handler("handler_req_id", handler_req_id) + .handler("handler_app_id", handler_app_id) .handler("handler_two_extractors", handler_two_extractors) .handler("handler_state_extractor", handler_state_extractor) .handler("listener", listener) @@ -156,6 +163,7 @@ async fn it_receives_various_messages_and_works_as_expected() { &[], BasicProperties::default() .with_reply_to(reply_to.into()) + .with_app_id("my_app_id".into()) .with_headers(headers), ) .await @@ -183,6 +191,9 @@ async fn it_receives_various_messages_and_works_as_expected() { send_msg("handler_req_id", "handler_message_reply_to").await; recv.recv().await.unwrap(); recv.recv().await.unwrap(); + send_msg("handler_app_id", "handler_message_reply_to").await; + recv.recv().await.unwrap(); + recv.recv().await.unwrap(); send_msg("handler_two_extractors", "handler_message_reply_to").await; recv.recv().await.unwrap(); recv.recv().await.unwrap(); @@ -236,6 +247,7 @@ async fn it_receives_various_messages_and_works_as_expected() { // "handler_channel", // "handler_delivery", // "handler_req_id", + // "handler_app_id", // "handler_two_extractors", "handler_state_extractor", "listener", @@ -253,6 +265,7 @@ async fn it_receives_various_messages_and_works_as_expected() { "handler_message", "handler_message", "handler_message", + "handler_message", "shutdown", ], recv_calls.as_ref()