From e7d881f07c11c574b6d5e03299058799a84bfe35 Mon Sep 17 00:00:00 2001 From: Kai Hudalla Date: Wed, 2 Oct 2024 10:42:14 +0200 Subject: [PATCH] Add simple LocalUriProvider implementation Added StaticUriProvider which is configured using static information. StaticUriProvider is supposed to be used by transport implementations and/or test cases. --- src/communication/default_notifier.rs | 21 +--- src/communication/default_pubsub.rs | 21 +--- src/communication/in_memory_rpc_client.rs | 14 +-- src/communication/in_memory_rpc_server.rs | 14 +-- src/lib.rs | 4 +- src/utransport.rs | 125 ++++++++++++++++++++++ 6 files changed, 138 insertions(+), 61 deletions(-) diff --git a/src/communication/default_notifier.rs b/src/communication/default_notifier.rs index efbe76b..814869f 100644 --- a/src/communication/default_notifier.rs +++ b/src/communication/default_notifier.rs @@ -107,27 +107,12 @@ mod tests { use protobuf::well_known_types::wrappers::StringValue; use crate::{ - utransport::{MockLocalUriProvider, MockTransport, MockUListener}, - UCode, UPriority, UStatus, UUri, UUID, + utransport::{MockTransport, MockUListener}, + StaticUriProvider, UCode, UPriority, UStatus, UUri, UUID, }; fn new_uri_provider() -> Arc { - let mut mock_uri_locator = MockLocalUriProvider::new(); - mock_uri_locator - .expect_get_resource_uri() - .returning(|resource_id| UUri { - ue_id: 0x0005, - ue_version_major: 0x02, - resource_id: resource_id as u32, - ..Default::default() - }); - mock_uri_locator.expect_get_source_uri().returning(|| UUri { - ue_id: 0x0005, - ue_version_major: 0x02, - resource_id: 0x0000, - ..Default::default() - }); - Arc::new(mock_uri_locator) + Arc::new(StaticUriProvider::new("", 0x0005, 0x02)) } #[tokio::test] diff --git a/src/communication/default_pubsub.rs b/src/communication/default_pubsub.rs index a0cecc7..08b6581 100644 --- a/src/communication/default_pubsub.rs +++ b/src/communication/default_pubsub.rs @@ -467,27 +467,12 @@ mod tests { use crate::{ communication::{notification::MockNotifier, pubsub::MockSubscriptionChangeHandler}, - utransport::{MockLocalUriProvider, MockTransport, MockUListener}, - UAttributes, UCode, UMessageType, UPriority, UStatus, UUri, UUID, + utransport::{MockTransport, MockUListener}, + StaticUriProvider, UAttributes, UCode, UMessageType, UPriority, UStatus, UUri, UUID, }; fn new_uri_provider() -> Arc { - let mut mock_uri_locator = MockLocalUriProvider::new(); - mock_uri_locator - .expect_get_resource_uri() - .returning(|resource_id| UUri { - ue_id: 0x0005, - ue_version_major: 0x02, - resource_id: resource_id as u32, - ..Default::default() - }); - mock_uri_locator.expect_get_source_uri().returning(|| UUri { - ue_id: 0x0005, - ue_version_major: 0x02, - resource_id: 0x0000, - ..Default::default() - }); - Arc::new(mock_uri_locator) + Arc::new(StaticUriProvider::new("", 0x0005, 0x02)) } fn succeding_notifier() -> Arc { diff --git a/src/communication/in_memory_rpc_client.rs b/src/communication/in_memory_rpc_client.rs index e8c8e96..a108aaa 100644 --- a/src/communication/in_memory_rpc_client.rs +++ b/src/communication/in_memory_rpc_client.rs @@ -298,20 +298,10 @@ mod tests { use protobuf::{well_known_types::wrappers::StringValue, Enum}; use tokio::{join, sync::Notify}; - use crate::{ - utransport::{MockLocalUriProvider, MockTransport}, - UMessageBuilder, UPriority, UUri, - }; + use crate::{utransport::MockTransport, StaticUriProvider, UMessageBuilder, UPriority, UUri}; fn new_uri_provider() -> Arc { - let mut mock_uri_locator = MockLocalUriProvider::new(); - mock_uri_locator.expect_get_source_uri().returning(|| UUri { - ue_id: 0x0005, - ue_version_major: 0x02, - resource_id: 0x0000, - ..Default::default() - }); - Arc::new(mock_uri_locator) + Arc::new(StaticUriProvider::new("", 0x0005, 0x02)) } fn service_method_uri() -> UUri { diff --git a/src/communication/in_memory_rpc_server.rs b/src/communication/in_memory_rpc_server.rs index 1e23943..f7e3173 100644 --- a/src/communication/in_memory_rpc_server.rs +++ b/src/communication/in_memory_rpc_server.rs @@ -291,22 +291,12 @@ mod tests { use tokio::sync::Notify; use crate::{ - communication::rpc::MockRequestHandler, - utransport::{MockLocalUriProvider, MockTransport}, + communication::rpc::MockRequestHandler, utransport::MockTransport, StaticUriProvider, UAttributes, UMessageType, UPriority, UUri, UUID, }; fn new_uri_provider() -> Arc { - let mut mock_uri_provider = MockLocalUriProvider::new(); - mock_uri_provider - .expect_get_resource_uri() - .returning(|resource_id| UUri { - ue_id: 0x0005, - ue_version_major: 0x02, - resource_id: resource_id as u32, - ..Default::default() - }); - Arc::new(mock_uri_provider) + Arc::new(StaticUriProvider::new("", 0x0005, 0x02)) } #[test_case(None, 0x4A10; "for empty origin filter")] diff --git a/src/lib.rs b/src/lib.rs index 36cf60f..3ea5898 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,7 +76,9 @@ mod ustatus; pub use ustatus::{UCode, UStatus}; mod utransport; -pub use utransport::{ComparableListener, LocalUriProvider, UListener, UTransport}; +pub use utransport::{ + ComparableListener, LocalUriProvider, StaticUriProvider, UListener, UTransport, +}; mod uuid; pub use uuid::UUID; diff --git a/src/utransport.rs b/src/utransport.rs index 1b2619d..158f27b 100644 --- a/src/utransport.rs +++ b/src/utransport.rs @@ -13,6 +13,7 @@ use std::fmt::{Debug, Formatter}; use std::hash::{Hash, Hasher}; +use std::num::TryFromIntError; use std::ops::Deref; use std::sync::Arc; @@ -26,6 +27,7 @@ use crate::{UCode, UMessage, UStatus, UUri}; /// /// Implementations may use arbitrary mechanisms to determine the information that /// is necessary for creating URIs, e.g. environment variables, configuration files etc. +// [impl->req~up-language-transport-api~1] #[cfg_attr(test, automock)] pub trait LocalUriProvider: Send + Sync { /// Gets the _authority_ used for URIs representing this uEntity's resources. @@ -37,6 +39,109 @@ pub trait LocalUriProvider: Send + Sync { fn get_source_uri(&self) -> UUri; } +/// A URI provider that is statically configured with the uEntity's authority, entity ID and version. +pub struct StaticUriProvider { + local_uri: UUri, +} + +impl StaticUriProvider { + /// Creates a new URI provider from static information. + /// + /// # Arguments + /// + /// * `authority` - The uEntity's authority name. + /// * `entity_id` - The entity identifier. + /// * `major_version` - The uEntity's major version. + /// + /// # Examples + /// + /// ```rust + /// use up_rust::{LocalUriProvider, StaticUriProvider}; + /// + /// let provider = StaticUriProvider::new("my-vehicle", 0x4210, 0x05); + /// assert_eq!(provider.get_authority(), "my-vehicle"); + /// ``` + pub fn new(authority: impl Into, entity_id: u32, major_version: u8) -> Self { + let local_uri = UUri { + authority_name: authority.into(), + ue_id: entity_id, + ue_version_major: major_version as u32, + resource_id: 0x0000, + ..Default::default() + }; + StaticUriProvider { local_uri } + } +} + +impl LocalUriProvider for StaticUriProvider { + fn get_authority(&self) -> String { + self.local_uri.authority_name.clone() + } + + fn get_resource_uri(&self, resource_id: u16) -> UUri { + let mut uri = self.local_uri.clone(); + uri.resource_id = resource_id as u32; + uri + } + + fn get_source_uri(&self) -> UUri { + self.local_uri.clone() + } +} + +impl TryFrom for StaticUriProvider { + type Error = TryFromIntError; + fn try_from(value: UUri) -> Result { + Self::try_from(&value) + } +} + +impl TryFrom<&UUri> for StaticUriProvider { + type Error = TryFromIntError; + /// Creates a URI provider from a UUri. + /// + /// # Arguments + /// + /// * `source_uri` - The UUri to take the entity's authority, entity ID and version information from. + /// The UUri's resource ID is ignored. + /// + /// # Errors + /// + /// Returns an error if the given UUri's major version property is not a `u8`. + /// + /// # Examples + /// + /// ```rust + /// use up_rust::{LocalUriProvider, StaticUriProvider, UUri}; + /// + /// let source_uri = UUri::try_from("//my-vehicle/4210/5/0").unwrap(); + /// assert!(StaticUriProvider::try_from(&source_uri).is_ok()); + /// ``` + /// + /// ## Invalid Major Version + /// + /// ```rust + /// use up_rust::{LocalUriProvider, StaticUriProvider, UUri}; + /// + /// let uuri_with_invalid_version = UUri { + /// authority_name: "".to_string(), + /// ue_id: 0x5430, + /// ue_version_major: 0x1234, // not a u8 + /// resource_id: 0x0000, + /// ..Default::default() + /// }; + /// assert!(StaticUriProvider::try_from(uuri_with_invalid_version).is_err()); + /// ``` + fn try_from(source_uri: &UUri) -> Result { + let major_version = u8::try_from(source_uri.ue_version_major)?; + Ok(StaticUriProvider::new( + &source_uri.authority_name, + source_uri.ue_id, + major_version, + )) + } +} + /// A handler for processing uProtocol messages. /// /// Implementations contain the details for what should occur when a message is received. @@ -294,6 +399,26 @@ mod tests { use super::*; + #[test] + fn test_static_uri_provider_get_source() { + let provider = StaticUriProvider::new("my-vehicle", 0x4210, 0x05); + let source_uri = provider.get_source_uri(); + assert_eq!(source_uri.authority_name, "my-vehicle"); + assert_eq!(source_uri.ue_id, 0x4210); + assert_eq!(source_uri.ue_version_major, 0x05); + assert_eq!(source_uri.resource_id, 0x0000); + } + + #[test] + fn test_static_uri_provider_get_resource() { + let provider = StaticUriProvider::new("my-vehicle", 0x4210, 0x05); + let resource_uri = provider.get_resource_uri(0x1234); + assert_eq!(resource_uri.authority_name, "my-vehicle"); + assert_eq!(resource_uri.ue_id, 0x4210); + assert_eq!(resource_uri.ue_version_major, 0x05); + assert_eq!(resource_uri.resource_id, 0x1234); + } + #[tokio::test] async fn test_deref_returns_wrapped_listener() { let mut mock_listener = MockUListener::new();