diff --git a/Cargo.toml b/Cargo.toml index 59bcbfa9..f926d0d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,7 +74,7 @@ tonic = { version = "0.11", features = ["tls"] } tonic-build = "0.11" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } -yang3 = { version = "0.5", features = ["bundled"] } +yang3 = { version = "0.6", features = ["bundled"] } [workspace.lints.rust] rust_2018_idioms = { level = "warn", priority = -1 } diff --git a/holo-daemon/src/northbound/client/api.rs b/holo-daemon/src/northbound/client/api.rs index 99453ef5..58777b81 100644 --- a/holo-daemon/src/northbound/client/api.rs +++ b/holo-daemon/src/northbound/client/api.rs @@ -44,12 +44,12 @@ pub mod client { #[derive(Debug)] pub struct GetResponse { - pub dtree: DataTree, + pub dtree: DataTree<'static>, } #[derive(Debug)] pub struct ValidateRequest { - pub config: DataTree, + pub config: DataTree<'static>, pub responder: Responder>, } @@ -71,13 +71,13 @@ pub mod client { #[derive(Debug)] pub struct ExecuteRequest { - pub data: DataTree, + pub data: DataTree<'static>, pub responder: Responder>, } #[derive(Debug)] pub struct ExecuteResponse { - pub data: DataTree, + pub data: DataTree<'static>, } #[derive(Debug)] @@ -98,7 +98,7 @@ pub mod client { #[derive(Debug)] pub struct GetTransactionResponse { - pub dtree: DataTree, + pub dtree: DataTree<'static>, } // ===== impl Request ===== @@ -126,7 +126,7 @@ pub enum DataType { #[derive(Debug)] pub enum CommitConfiguration { - Merge(DataTree), - Replace(DataTree), - Change(DataDiff), + Merge(DataTree<'static>), + Replace(DataTree<'static>), + Change(DataDiff<'static>), } diff --git a/holo-daemon/src/northbound/client/gnmi.rs b/holo-daemon/src/northbound/client/gnmi.rs index f2f31cb5..cb45f6e4 100644 --- a/holo-daemon/src/northbound/client/gnmi.rs +++ b/holo-daemon/src/northbound/client/gnmi.rs @@ -279,7 +279,7 @@ impl proto::GNmi for GNmiService { impl GNmiService { fn gen_update_ietf_json( &self, - dtree: DataTree, + dtree: DataTree<'static>, _models: &[proto::ModelData], ) -> Vec { dtree @@ -343,7 +343,7 @@ impl GNmiService { fn gen_update_proto( &self, - dtree: DataTree, + dtree: DataTree<'static>, _models: &[proto::ModelData], ) -> Vec { dtree @@ -398,7 +398,7 @@ impl GNmiService { .collect() } - async fn get_running(&self) -> Result { + async fn get_running(&self) -> Result, Status> { // Create oneshot channel to receive response back from the northbound. let (responder_tx, responder_rx) = oneshot::channel(); diff --git a/holo-daemon/src/northbound/client/grpc.rs b/holo-daemon/src/northbound/client/grpc.rs index 2ad1a097..ae6dcc7e 100644 --- a/holo-daemon/src/northbound/client/grpc.rs +++ b/holo-daemon/src/northbound/client/grpc.rs @@ -416,7 +416,7 @@ fn get_timestamp() -> i64 { } fn data_tree_init( - dtree: &DataTree, + dtree: &DataTree<'static>, encoding: proto::Encoding, printer_flags: DataPrinterFlags, ) -> Result { @@ -444,7 +444,9 @@ fn data_tree_init( }) } -fn data_tree_get(data_tree: &proto::DataTree) -> Result { +fn data_tree_get( + data_tree: &proto::DataTree, +) -> Result, Status> { let yang_ctx = YANG_CTX.get().unwrap(); let encoding = proto::Encoding::try_from(data_tree.encoding) .map_err(|_| Status::invalid_argument("Invalid data encoding"))?; @@ -474,7 +476,9 @@ fn data_tree_get(data_tree: &proto::DataTree) -> Result { .map_err(|error| Status::invalid_argument(error.to_string())) } -fn data_diff_get(data_tree: &proto::DataTree) -> Result { +fn data_diff_get( + data_tree: &proto::DataTree, +) -> Result, Status> { let yang_ctx = YANG_CTX.get().unwrap(); let encoding = proto::Encoding::try_from(data_tree.encoding) .map_err(|_| Status::invalid_argument("Invalid data encoding"))?; @@ -505,7 +509,7 @@ fn data_diff_get(data_tree: &proto::DataTree) -> Result { .map_err(|error| Status::invalid_argument(error.to_string())) } -fn rpc_get(data_tree: &proto::DataTree) -> Result { +fn rpc_get(data_tree: &proto::DataTree) -> Result, Status> { let yang_ctx = YANG_CTX.get().unwrap(); let encoding = proto::Encoding::try_from(data_tree.encoding) .map_err(|_| Status::invalid_argument("Invalid data encoding"))?; diff --git a/holo-daemon/src/northbound/core.rs b/holo-daemon/src/northbound/core.rs index 24dfa9da..f0340533 100644 --- a/holo-daemon/src/northbound/core.rs +++ b/holo-daemon/src/northbound/core.rs @@ -35,7 +35,7 @@ use crate::northbound::{db, yang, Error, Result}; pub struct Northbound { // YANG-modeled running configuration. - running_config: Arc, + running_config: Arc>, // Non-volatile storage. db: Database, @@ -72,7 +72,7 @@ pub struct Transaction { // Configuration that was committed. #[serde(with = "holo_yang::serde::data_tree")] - pub configuration: DataTree, + pub configuration: DataTree<'static>, } #[derive(Debug)] @@ -87,7 +87,7 @@ pub struct ConfirmedCommit { #[derive(Debug)] pub struct Rollback { - configuration: DataTree, + configuration: DataTree<'static>, #[allow(dead_code)] timeout: TimeoutTask, } @@ -225,7 +225,7 @@ impl Northbound { // Processes a `Validate` message received from an external client. async fn process_client_validate( &mut self, - candidate: DataTree, + candidate: DataTree<'static>, ) -> Result { let candidate = Arc::new(candidate); @@ -275,7 +275,7 @@ impl Northbound { // Processes an `Execute` message received from an external client. async fn process_client_execute( &mut self, - data: DataTree, + data: DataTree<'static>, ) -> Result { let data = self.execute(data).await?; Ok(capi::client::ExecuteResponse { data }) @@ -330,7 +330,7 @@ impl Northbound { // fails to be validated, or if one or more resources fail to be allocated. async fn create_transaction( &mut self, - candidate: DataTree, + candidate: DataTree<'static>, comment: String, confirmed_timeout: u32, ) -> Result { @@ -434,7 +434,7 @@ impl Northbound { // Request all data providers to validate the candidate configuration. async fn validate_notify( &mut self, - candidate: &Arc, + candidate: &Arc>, ) -> std::result::Result<(), northbound::error::Error> { let mut handles = Vec::new(); @@ -470,7 +470,7 @@ impl Northbound { async fn commit_phase_notify( &mut self, phase: CommitPhase, - candidate: &Arc, + candidate: &Arc>, changes: &[ConfigChange], ) -> std::result::Result<(), northbound::error::Error> { // Spawn one task per data provider. @@ -514,7 +514,10 @@ impl Northbound { } // Gets a full or partial copy of the running configuration. - fn get_configuration(&self, path: Option<&str>) -> Result { + fn get_configuration( + &self, + path: Option<&str>, + ) -> Result> { match path { Some(path) => { let yang_ctx = YANG_CTX.get().unwrap(); @@ -538,7 +541,7 @@ impl Northbound { // Gets dynamically generated operational data for the provided path. The // request might span multiple data providers. - async fn get_state(&self, path: Option<&str>) -> Result { + async fn get_state(&self, path: Option<&str>) -> Result> { let yang_ctx = YANG_CTX.get().unwrap(); let mut dtree = DataTree::new(yang_ctx); @@ -563,7 +566,10 @@ impl Northbound { } // Invoke a YANG RPC or Action. - async fn execute(&self, data: DataTree) -> Result { + async fn execute( + &self, + data: DataTree<'static>, + ) -> Result> { let yang_ctx = YANG_CTX.get().unwrap(); let mut dtree = DataTree::new(yang_ctx); @@ -591,7 +597,7 @@ impl Northbound { // ===== impl ConfirmedCommit ===== impl ConfirmedCommit { - fn start(&mut self, configuration: DataTree, timeout: u32) { + fn start(&mut self, configuration: DataTree<'static>, timeout: u32) { debug!(%timeout, "starting confirmed commit timeout"); let timeout = self.timeout_task(timeout); diff --git a/holo-northbound/build.rs b/holo-northbound/build.rs index 2869f292..86d3f15b 100644 --- a/holo-northbound/build.rs +++ b/holo-northbound/build.rs @@ -225,7 +225,7 @@ impl<'a> StructBuilder<'a> { // into_data_node() function implementation. writeln!( output, - "{}fn into_data_node(self: Box, dnode: &mut DataNodeRef<'_>) {{", + "{}fn into_data_node(self: Box, dnode: &mut DataNodeRef<'_, '_>) {{", indent2 ) .unwrap(); diff --git a/holo-northbound/src/api.rs b/holo-northbound/src/api.rs index d02c7903..5df50180 100644 --- a/holo-northbound/src/api.rs +++ b/holo-northbound/src/api.rs @@ -47,7 +47,7 @@ pub mod daemon { #[derive(Debug, Deserialize, Serialize)] pub struct ValidateRequest { #[serde(with = "holo_yang::serde::data_tree::arc")] - pub config: Arc, + pub config: Arc>, #[serde(skip)] pub responder: Option>>, } @@ -59,9 +59,9 @@ pub mod daemon { pub struct CommitRequest { pub phase: CommitPhase, #[serde(with = "holo_yang::serde::data_tree::arc")] - pub old_config: Arc, + pub old_config: Arc>, #[serde(with = "holo_yang::serde::data_tree::arc")] - pub new_config: Arc, + pub new_config: Arc>, pub changes: ConfigChanges, #[serde(skip)] pub responder: Option>>, @@ -79,20 +79,20 @@ pub mod daemon { #[derive(Debug)] pub struct GetResponse { - pub data: DataTree, + pub data: DataTree<'static>, } #[derive(Debug, Deserialize, Serialize)] pub struct RpcRequest { #[serde(with = "holo_yang::serde::data_tree")] - pub data: DataTree, + pub data: DataTree<'static>, #[serde(skip)] pub responder: Option>>, } #[derive(Debug)] pub struct RpcResponse { - pub data: DataTree, + pub data: DataTree<'static>, } } @@ -102,6 +102,6 @@ pub mod provider { #[derive(Debug)] pub struct Notification { - pub data: DataTree, + pub data: DataTree<'static>, } } diff --git a/holo-northbound/src/configuration.rs b/holo-northbound/src/configuration.rs index 4bddd0e6..c77b5c1f 100644 --- a/holo-northbound/src/configuration.rs +++ b/holo-northbound/src/configuration.rs @@ -60,9 +60,9 @@ pub struct CallbackArgs<'a, P: Provider> { pub event_queue: &'a mut BTreeSet, pub list_entry: P::ListEntry, pub resource: &'a mut Option, - pub old_config: &'a Arc, - pub new_config: &'a Arc, - pub dnode: DataNodeRef<'a>, + pub old_config: &'a Arc>, + pub new_config: &'a Arc>, + pub dnode: DataNodeRef<'a, 'static>, } // @@ -80,7 +80,7 @@ pub struct ValidationCallbacksBuilder { #[derive(Debug)] pub struct ValidationCallbackArgs<'a> { - pub dnode: DataNodeRef<'a>, + pub dnode: DataNodeRef<'a, 'static>, } // @@ -93,7 +93,7 @@ pub type ConfigChanges = Vec; pub type CallbackLookup = for<'a> fn( &'a mut P, list_entry: P::ListEntry, - dnode: DataNodeRef<'a>, + dnode: DataNodeRef<'a, 'static>, ) -> P::ListEntry; pub type CallbackPhaseOne

= @@ -396,8 +396,8 @@ impl ValidationCallbacksBuilder { async fn process_commit_local

( provider: &mut P, phase: CommitPhase, - old_config: &Arc, - new_config: &Arc, + old_config: &Arc>, + new_config: &Arc>, changes: &ConfigChanges, resources: &mut Vec>, ) -> Result<(), Error> @@ -478,8 +478,8 @@ where async fn process_commit_relayed

( provider: &P, phase: CommitPhase, - old_config: &Arc, - new_config: &Arc, + old_config: &Arc>, + new_config: &Arc>, relayed_changes: ConfigChanges, ) -> Result<(), Error> where @@ -512,7 +512,7 @@ fn lookup_list_entry

( phase: CommitPhase, operation: CallbackOp, callbacks: &Callbacks

, - dnode: &DataNodeRef<'_>, + dnode: &DataNodeRef<'_, 'static>, ) -> P::ListEntry where P: Provider, @@ -542,7 +542,7 @@ where async fn validate_configuration

( provider: &P, - config: &Arc, + config: &Arc>, ) -> Result<(), Error> where P: Provider, @@ -569,7 +569,7 @@ where // ===== global functions ===== -pub fn changes_from_diff(diff: &DataDiff) -> ConfigChanges { +pub fn changes_from_diff(diff: &DataDiff<'static>) -> ConfigChanges { let mut changes = vec![]; for (op, dnode) in diff.iter() { @@ -639,7 +639,7 @@ pub fn changes_from_diff(diff: &DataDiff) -> ConfigChanges { pub(crate) async fn process_validate

( provider: &P, - config: Arc, + config: Arc>, ) -> Result where P: Provider, @@ -670,8 +670,8 @@ where pub(crate) async fn process_commit

( provider: &mut P, phase: CommitPhase, - old_config: Arc, - new_config: Arc, + old_config: Arc>, + new_config: Arc>, mut changes: ConfigChanges, resources: &mut Vec>, ) -> Result diff --git a/holo-northbound/src/rpc.rs b/holo-northbound/src/rpc.rs index 61fffd30..bcbacfcd 100644 --- a/holo-northbound/src/rpc.rs +++ b/holo-northbound/src/rpc.rs @@ -31,7 +31,7 @@ pub struct CallbacksBuilder { #[derive(Debug)] pub struct CallbackArgs<'a> { - pub data: &'a mut DataTree, + pub data: &'a mut DataTree<'static>, pub rpc_path: &'a str, } @@ -58,7 +58,7 @@ pub trait Provider: ProviderBase { fn relay_rpc( &self, - _rpc: DataNodeRef<'_>, + _rpc: DataNodeRef<'_, '_>, ) -> Result>, String> { Ok(None) } @@ -145,7 +145,7 @@ where async fn process_rpc_local

( provider: &mut P, - mut data: DataTree, + mut data: DataTree<'static>, rpc_data_path: String, rpc_schema_path: String, ) -> Result @@ -170,7 +170,7 @@ where } async fn process_rpc_relayed( - mut data: DataTree, + mut data: DataTree<'static>, children_nb_tx: Vec, ) -> Result { for nb_tx in children_nb_tx { @@ -194,7 +194,9 @@ async fn process_rpc_relayed( Ok(response) } -fn find_rpc(data: &DataTree) -> Result, Error> { +fn find_rpc<'a>( + data: &'a DataTree<'static>, +) -> Result, Error> { data.traverse() .find(|dnode| { matches!( @@ -209,7 +211,7 @@ fn find_rpc(data: &DataTree) -> Result, Error> { pub(crate) async fn process_rpc

( provider: &mut P, - data: DataTree, + data: DataTree<'static>, ) -> Result where P: Provider, diff --git a/holo-northbound/src/state.rs b/holo-northbound/src/state.rs index 29af0947..fc49d321 100644 --- a/holo-northbound/src/state.rs +++ b/holo-northbound/src/state.rs @@ -216,7 +216,7 @@ where fn iterate_node<'a, P>( provider: &'a P, cbs: &Callbacks

, - dnode: &mut DataNodeRef<'_>, + dnode: &mut DataNodeRef<'_, '_>, snode: &SchemaNode<'_>, list_entry: &P::ListEntry<'a>, relay_list: &mut Vec, @@ -248,7 +248,7 @@ where fn iterate_list<'a, P>( provider: &'a P, cbs: &Callbacks

, - dnode: &mut DataNodeRef<'_>, + dnode: &mut DataNodeRef<'_, '_>, snode: &SchemaNode<'_>, parent_list_entry: &P::ListEntry<'a>, relay_list: &mut Vec, @@ -277,7 +277,7 @@ where fn iterate_list_entry<'a, P>( provider: &'a P, cbs: &Callbacks

, - dnode: &mut DataNodeRef<'_>, + dnode: &mut DataNodeRef<'_, '_>, snode: &SchemaNode<'_>, list_entry: P::ListEntry<'a>, relay_list: &mut Vec, @@ -335,7 +335,7 @@ where fn iterate_container<'a, P>( provider: &'a P, cbs: &Callbacks

, - dnode: &mut DataNodeRef<'_>, + dnode: &mut DataNodeRef<'_, '_>, snode: &SchemaNode<'_>, list_entry: &P::ListEntry<'a>, relay_list: &mut Vec, @@ -380,7 +380,7 @@ where fn iterate_children<'a, P>( provider: &'a P, cbs: &Callbacks

, - dnode: &mut DataNodeRef<'_>, + dnode: &mut DataNodeRef<'_, '_>, snode: &SchemaNode<'_>, list_entry: &P::ListEntry<'a>, relay_list: &mut Vec, @@ -425,7 +425,7 @@ where fn lookup_list_entry<'a, P>( provider: &'a P, cbs: &Callbacks

, - dnode: &DataNodeRef<'_>, + dnode: &DataNodeRef<'_, '_>, ) -> P::ListEntry<'a> where P: Provider, diff --git a/holo-protocol/src/test/stub/northbound.rs b/holo-protocol/src/test/stub/northbound.rs index 3ae8b1e1..f31b5196 100644 --- a/holo-protocol/src/test/stub/northbound.rs +++ b/holo-protocol/src/test/stub/northbound.rs @@ -20,8 +20,8 @@ use crate::test::stub::UPDATE_OUTPUTS; // Stub northbound layer. #[derive(Debug)] pub struct NorthboundStub { - running_config: Arc, - state_cache: Option, + running_config: Arc>, + state_cache: Option>, daemon_tx: NbDaemonSender, } @@ -121,7 +121,7 @@ impl NorthboundStub { self.state_cache = Some(state); } - async fn get_state(&self, path: &str) -> DataTree { + async fn get_state(&self, path: &str) -> DataTree<'static> { // Prepare request. let (responder_tx, responder_rx) = oneshot::channel(); let request = api::daemon::Request::Get(api::daemon::GetRequest { @@ -207,7 +207,11 @@ impl NorthboundStub { self.state_cache = Some(actual.duplicate().unwrap()); } - async fn commit(&mut self, candidate: DataTree, data_diff: DataDiff) { + async fn commit( + &mut self, + candidate: DataTree<'static>, + data_diff: DataDiff<'static>, + ) { // Get configuration changes from data diff. let changes = configuration::changes_from_diff(&data_diff); @@ -225,7 +229,7 @@ impl NorthboundStub { async fn commit_phase_notify( &self, phase: CommitPhase, - candidate: &Arc, + candidate: &Arc>, changes: &ConfigChanges, ) { // Prepare request. @@ -252,7 +256,7 @@ impl NorthboundStub { // ===== helper functions ===== -fn dtree_print(dtree: &DataTree) -> String { +fn dtree_print(dtree: &DataTree<'static>) -> String { dtree .print_string( DataFormat::JSON, diff --git a/holo-routing/src/northbound/rpc.rs b/holo-routing/src/northbound/rpc.rs index b4ea1c96..f39a6ab0 100644 --- a/holo-routing/src/northbound/rpc.rs +++ b/holo-routing/src/northbound/rpc.rs @@ -35,7 +35,7 @@ impl Provider for Master { fn relay_rpc( &self, - rpc: DataNodeRef<'_>, + rpc: DataNodeRef<'_, '_>, ) -> Result>, String> { let (protocol, name) = find_instance(rpc)?; @@ -66,7 +66,7 @@ impl Provider for Master { // easy way to identify the protocol type and name. YANG actions would greatly // simplify this. fn find_instance( - rpc: DataNodeRef<'_>, + rpc: DataNodeRef<'_, '_>, ) -> Result<(Protocol, Option), String> { let (protocol, name) = match rpc.schema().module().name() { "ietf-bgp" => { diff --git a/holo-utils/src/yang.rs b/holo-utils/src/yang.rs index c809a0b5..7628c57d 100644 --- a/holo-utils/src/yang.rs +++ b/holo-utils/src/yang.rs @@ -106,7 +106,7 @@ impl<'a> SchemaNodeExt for SchemaNode<'a> { // ===== impl DataNodeRef ===== -impl<'a> DataNodeRefExt for DataNodeRef<'a> { +impl<'a, 'b> DataNodeRefExt for DataNodeRef<'a, 'b> { fn exists(&self, path: &str) -> bool { self.find_xpath(path).unwrap().next().is_some() } @@ -356,7 +356,7 @@ impl<'a> DataNodeRefExt for DataNodeRef<'a> { // ===== helper functions ===== -fn panic_wrong_dnode_type(dnode: &DataNodeRef<'_>, expected: &str) -> ! { +fn panic_wrong_dnode_type(dnode: &DataNodeRef<'_, '_>, expected: &str) -> ! { panic!( "wrong data node type (was expecting {}): {}", expected, diff --git a/holo-yang/Cargo.toml b/holo-yang/Cargo.toml index c098a06c..143f803b 100644 --- a/holo-yang/Cargo.toml +++ b/holo-yang/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "holo-yang" -version = "0.5.3" +version = "0.5.4" authors.workspace = true license.workspace = true edition.workspace = true diff --git a/holo-yang/src/lib.rs b/holo-yang/src/lib.rs index 6e11cabf..55c599bc 100644 --- a/holo-yang/src/lib.rs +++ b/holo-yang/src/lib.rs @@ -284,7 +284,7 @@ pub trait TryFromYang: Sized { pub trait YangObject { // Initialize a given YANG data node with attributes from the current // object. - fn into_data_node(self: Box, dnode: &mut DataNodeRef<'_>); + fn into_data_node(self: Box, dnode: &mut DataNodeRef<'_, '_>); // Return the keys of the list, or an empty string for containers or keyless // lists. diff --git a/holo-yang/src/serde/data_tree.rs b/holo-yang/src/serde/data_tree.rs index 3402abc7..273e3958 100644 --- a/holo-yang/src/serde/data_tree.rs +++ b/holo-yang/src/serde/data_tree.rs @@ -15,7 +15,7 @@ use yang3::data::{ use crate::YANG_CTX; // Serialize YANG data tree to JSON. -pub fn serialize(dtree: &DataTree, s: S) -> Result +pub fn serialize(dtree: &DataTree<'static>, s: S) -> Result where S: Serializer, { @@ -32,7 +32,9 @@ where } // Deserialize YANG data tree from JSON. -pub fn deserialize<'de, D>(deserializer: D) -> Result +pub fn deserialize<'de, D>( + deserializer: D, +) -> Result, D::Error> where D: serde::de::Deserializer<'de>, { @@ -51,7 +53,10 @@ where pub mod arc { use super::*; - pub fn serialize(dtree: &DataTree, s: S) -> Result + pub fn serialize( + dtree: &DataTree<'static>, + s: S, + ) -> Result where S: Serializer, { @@ -60,7 +65,7 @@ pub mod arc { pub fn deserialize<'de, D>( deserializer: D, - ) -> Result, D::Error> + ) -> Result>, D::Error> where D: serde::de::Deserializer<'de>, {