diff --git a/Cargo.lock b/Cargo.lock index 20230e6fb2e..80d8ca87c62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -983,7 +983,7 @@ checksum = "c51b96c5a8ed8705b40d655273bc4212cbbf38d4e3be2788f36306f154523ec7" dependencies = [ "bytes 1.8.0", "core-error", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "log", "object", "thiserror 1.0.69", @@ -3052,18 +3052,18 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", - "serde", ] [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", "foldhash", + "serde", ] [[package]] @@ -3569,7 +3569,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -4637,7 +4637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "crc32fast", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "indexmap 2.6.0", "memchr", ] @@ -4880,7 +4880,7 @@ dependencies = [ "cfg-if", "core2", "futures-util", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "hex", "miette", "minicbor", diff --git a/examples/rust/file_transfer/examples/receiver.rs b/examples/rust/file_transfer/examples/receiver.rs index 5c2286cd543..a0c20aa7ea2 100644 --- a/examples/rust/file_transfer/examples/receiver.rs +++ b/examples/rust/file_transfer/examples/receiver.rs @@ -58,7 +58,7 @@ impl Worker for FileReception { Ok(n) => { self.written_size += n; if self.written_size == self.size { - ctx.stop().await?; + ctx.shutdown_node().await?; } } Err(e) => { @@ -71,7 +71,7 @@ impl Worker for FileReception { ); } } - FileData::Quit => ctx.stop().await?, + FileData::Quit => ctx.shutdown_node().await?, } Ok(()) @@ -81,7 +81,7 @@ impl Worker for FileReception { #[ockam::node] async fn main(ctx: Context) -> Result<()> { let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an Identity to represent Receiver. let receiver = node.create_identity().await?; @@ -90,13 +90,14 @@ async fn main(ctx: Context) -> Result<()> { let secure_channel_listener_options = SecureChannelListenerOptions::new().as_consumer(&tcp_options.flow_control_id()); - node.flow_controls() - .add_consumer("receiver", &secure_channel_listener_options.spawner_flow_control_id()); + node.flow_controls().add_consumer( + &"receiver".into(), + &secure_channel_listener_options.spawner_flow_control_id(), + ); // Create a secure channel listener for Receiver that will wait for requests to // initiate an Authenticated Key Exchange. - node.create_secure_channel_listener(&receiver, "listener", secure_channel_listener_options) - .await?; + node.create_secure_channel_listener(&receiver, "listener", secure_channel_listener_options)?; // The computer that is running this program is likely within a private network and // not accessible over the internet. @@ -116,8 +117,8 @@ async fn main(ctx: Context) -> Result<()> { println!("{}", relay.remote_address()); // Start a worker, of type FileReception, at address "receiver". - node.start_worker("receiver", FileReception::default()).await?; + node.start_worker("receiver", FileReception::default())?; - // We won't call ctx.stop() here, this program will quit when the file will be entirely received + // We won't call ctx.shutdown_node() here, this program will quit when the file will be entirely received Ok(()) } diff --git a/examples/rust/file_transfer/examples/sender.rs b/examples/rust/file_transfer/examples/sender.rs index f80288b91f0..dda02b88313 100644 --- a/examples/rust/file_transfer/examples/sender.rs +++ b/examples/rust/file_transfer/examples/sender.rs @@ -32,7 +32,7 @@ async fn main(ctx: Context) -> Result<()> { let opt = Sender::parse(); let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an Identity to represent Sender. let sender = node.create_identity().await?; @@ -94,6 +94,6 @@ async fn main(ctx: Context) -> Result<()> { } } - // We won't call ctx.stop() here, this program will run until you stop it with Ctrl-C + // We won't call ctx.shutdown_node() here, this program will run until you stop it with Ctrl-C Ok(()) } diff --git a/examples/rust/get_started/examples/01-node.rs b/examples/rust/get_started/examples/01-node.rs index 1f727a2652f..1109e228585 100644 --- a/examples/rust/get_started/examples/01-node.rs +++ b/examples/rust/get_started/examples/01-node.rs @@ -9,5 +9,5 @@ async fn main(ctx: Context) -> Result<()> { let mut node = node(ctx).await?; // Stop the node as soon as it starts. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/02-worker.rs b/examples/rust/get_started/examples/02-worker.rs index 50e76fee94d..2b85f4cd204 100644 --- a/examples/rust/get_started/examples/02-worker.rs +++ b/examples/rust/get_started/examples/02-worker.rs @@ -9,7 +9,7 @@ async fn main(ctx: Context) -> Result<()> { let mut node = node(ctx).await?; // Start a worker, of type Echoer, at address "echoer" - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; // Send a message to the worker at address "echoer". node.send("echoer", "Hello Ockam!".to_string()).await?; @@ -19,5 +19,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply.into_body()?); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/03-routing-many-hops.rs b/examples/rust/get_started/examples/03-routing-many-hops.rs index 71c35cfedb8..5a9e58e537d 100644 --- a/examples/rust/get_started/examples/03-routing-many-hops.rs +++ b/examples/rust/get_started/examples/03-routing-many-hops.rs @@ -9,12 +9,12 @@ async fn main(ctx: Context) -> Result<()> { let mut node = node(ctx).await?; // Start an Echoer worker at address "echoer" - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; // Start 3 hop workers at addresses "h1", "h2" and "h3". - node.start_worker("h1", Hop).await?; - node.start_worker("h2", Hop).await?; - node.start_worker("h3", Hop).await?; + node.start_worker("h1", Hop)?; + node.start_worker("h2", Hop)?; + node.start_worker("h3", Hop)?; // Send a message to the echoer worker via the "h1", "h2", and "h3" workers let r = route!["h1", "h2", "h3", "echoer"]; @@ -25,5 +25,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply.into_body()?); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/03-routing.rs b/examples/rust/get_started/examples/03-routing.rs index b29ecfc573c..aa73780921d 100644 --- a/examples/rust/get_started/examples/03-routing.rs +++ b/examples/rust/get_started/examples/03-routing.rs @@ -9,10 +9,10 @@ async fn main(ctx: Context) -> Result<()> { let mut node = node(ctx).await?; // Start a worker, of type Echoer, at address "echoer" - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; // Start a worker, of type Hop, at address "h1" - node.start_worker("h1", Hop).await?; + node.start_worker("h1", Hop)?; // Send a message to the worker at address "echoer", // via the worker at address "h1" @@ -23,5 +23,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply.into_body()?); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/04-routing-over-transport-initiator.rs b/examples/rust/get_started/examples/04-routing-over-transport-initiator.rs index c62f3b48d70..4467fc79ce8 100644 --- a/examples/rust/get_started/examples/04-routing-over-transport-initiator.rs +++ b/examples/rust/get_started/examples/04-routing-over-transport-initiator.rs @@ -9,7 +9,7 @@ async fn main(ctx: Context) -> Result<()> { let mut node = node(ctx).await?; // Initialize the TCP Transport. - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create a TCP connection to a different node. let connection_to_responder = tcp.connect("localhost:4000", TcpConnectionOptions::new()).await?; @@ -22,5 +22,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/04-routing-over-transport-responder.rs b/examples/rust/get_started/examples/04-routing-over-transport-responder.rs index c29e1cf216f..0a6b698b15a 100644 --- a/examples/rust/get_started/examples/04-routing-over-transport-responder.rs +++ b/examples/rust/get_started/examples/04-routing-over-transport-responder.rs @@ -11,17 +11,18 @@ async fn main(ctx: Context) -> Result<()> { let node = node(ctx).await?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an echoer worker - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; // Create a TCP listener and wait for incoming connections. let listener = tcp.listen("127.0.0.1:4000", TcpListenerOptions::new()).await?; // Allow access to the Echoer via TCP connections from the TCP listener - node.flow_controls().add_consumer("echoer", listener.flow_control_id()); + node.flow_controls() + .add_consumer(&"echoer".into(), listener.flow_control_id()); - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/04-routing-over-transport-two-hops-initiator.rs b/examples/rust/get_started/examples/04-routing-over-transport-two-hops-initiator.rs index b75f588b4e6..373309c8fa1 100644 --- a/examples/rust/get_started/examples/04-routing-over-transport-two-hops-initiator.rs +++ b/examples/rust/get_started/examples/04-routing-over-transport-two-hops-initiator.rs @@ -9,7 +9,7 @@ async fn main(ctx: Context) -> Result<()> { let mut node = node(ctx).await?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create a TCP connection to the middle node. let connection_to_middle_node = tcp.connect("localhost:3000", TcpConnectionOptions::new()).await?; @@ -21,5 +21,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/04-routing-over-transport-two-hops-middle.rs b/examples/rust/get_started/examples/04-routing-over-transport-two-hops-middle.rs index 600bc776c22..b53116f20d0 100644 --- a/examples/rust/get_started/examples/04-routing-over-transport-two-hops-middle.rs +++ b/examples/rust/get_started/examples/04-routing-over-transport-two-hops-middle.rs @@ -13,22 +13,21 @@ async fn main(ctx: Context) -> Result<()> { let node = node(ctx).await?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create a TCP connection to the responder node. let connection_to_responder = tcp.connect("127.0.0.1:4000", TcpConnectionOptions::new()).await?; // Create and start a Relay worker - node.start_worker("forward_to_responder", Relay::new(connection_to_responder)) - .await?; + node.start_worker("forward_to_responder", Relay::new(connection_to_responder))?; // Create a TCP listener and wait for incoming connections. let listener = tcp.listen("127.0.0.1:3000", TcpListenerOptions::new()).await?; // Allow access to the Relay via TCP connections from the TCP listener node.flow_controls() - .add_consumer("forward_to_responder", listener.flow_control_id()); + .add_consumer(&"forward_to_responder".into(), listener.flow_control_id()); - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/04-routing-over-transport-two-hops-responder.rs b/examples/rust/get_started/examples/04-routing-over-transport-two-hops-responder.rs index c29e1cf216f..0a6b698b15a 100644 --- a/examples/rust/get_started/examples/04-routing-over-transport-two-hops-responder.rs +++ b/examples/rust/get_started/examples/04-routing-over-transport-two-hops-responder.rs @@ -11,17 +11,18 @@ async fn main(ctx: Context) -> Result<()> { let node = node(ctx).await?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an echoer worker - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; // Create a TCP listener and wait for incoming connections. let listener = tcp.listen("127.0.0.1:4000", TcpListenerOptions::new()).await?; // Allow access to the Echoer via TCP connections from the TCP listener - node.flow_controls().add_consumer("echoer", listener.flow_control_id()); + node.flow_controls() + .add_consumer(&"echoer".into(), listener.flow_control_id()); - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/04-udp-transport-initiator.rs b/examples/rust/get_started/examples/04-udp-transport-initiator.rs index c0096ef4da9..1aef74c5f21 100644 --- a/examples/rust/get_started/examples/04-udp-transport-initiator.rs +++ b/examples/rust/get_started/examples/04-udp-transport-initiator.rs @@ -21,5 +21,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/04-udp-transport-responder.rs b/examples/rust/get_started/examples/04-udp-transport-responder.rs index 59dc82fbfa0..f086e0e9897 100644 --- a/examples/rust/get_started/examples/04-udp-transport-responder.rs +++ b/examples/rust/get_started/examples/04-udp-transport-responder.rs @@ -22,10 +22,11 @@ async fn main(ctx: Context) -> Result<()> { .await?; // Create an echoer worker - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; - node.flow_controls().add_consumer("echoer", bind.flow_control_id()); + node.flow_controls() + .add_consumer(&"echoer".into(), bind.flow_control_id()); - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/04-unix-domain-socket-transport-initiator.rs b/examples/rust/get_started/examples/04-unix-domain-socket-transport-initiator.rs index fcfddfe7ba3..f7a9ff9b8e5 100644 --- a/examples/rust/get_started/examples/04-unix-domain-socket-transport-initiator.rs +++ b/examples/rust/get_started/examples/04-unix-domain-socket-transport-initiator.rs @@ -25,5 +25,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply.into_body()?); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/04-unix-domain-socket-transport-responder.rs b/examples/rust/get_started/examples/04-unix-domain-socket-transport-responder.rs index a654375e574..c0b23d1982c 100644 --- a/examples/rust/get_started/examples/04-unix-domain-socket-transport-responder.rs +++ b/examples/rust/get_started/examples/04-unix-domain-socket-transport-responder.rs @@ -17,8 +17,8 @@ async fn main(ctx: Context) -> Result<()> { uds.listen("/tmp/ockam-example-echoer").await?; // Create an echoer worker - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-initiator.rs b/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-initiator.rs index bcf9fe981ce..0ca507f17a1 100644 --- a/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-initiator.rs +++ b/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-initiator.rs @@ -14,7 +14,7 @@ async fn main(ctx: Context) -> Result<()> { let alice = node.create_identity().await?; // Create a TCP connection to the middle node. - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; let connection_to_middle_node = tcp.connect("localhost:3000", TcpConnectionOptions::new()).await?; // Connect to a secure channel listener and perform a handshake. @@ -31,5 +31,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-middle.rs b/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-middle.rs index dcb5e9d30ce..dbd98e19f24 100644 --- a/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-middle.rs +++ b/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-middle.rs @@ -13,21 +13,20 @@ async fn main(ctx: Context) -> Result<()> { let node = node(ctx).await?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create a TCP connection to Bob. let connection_to_bob = tcp.connect("127.0.0.1:4000", TcpConnectionOptions::new()).await?; // Start a Relay to forward messages to Bob using the TCP connection. - node.start_worker("forward_to_bob", Relay::new(route![connection_to_bob])) - .await?; + node.start_worker("forward_to_bob", Relay::new(route![connection_to_bob]))?; // Create a TCP listener and wait for incoming connections. let listener = tcp.listen("127.0.0.1:3000", TcpListenerOptions::new()).await?; node.flow_controls() - .add_consumer("forward_to_bob", listener.flow_control_id()); + .add_consumer(&"forward_to_bob".into(), listener.flow_control_id()); - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-responder.rs b/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-responder.rs index f85c295c4d7..39b7d55448f 100644 --- a/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-responder.rs +++ b/examples/rust/get_started/examples/05-secure-channel-over-two-transport-hops-responder.rs @@ -12,9 +12,9 @@ async fn main(ctx: Context) -> Result<()> { let node = node(ctx).await?; // Initialize the TCP Transport. - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; let bob = node.create_identity().await?; @@ -23,18 +23,16 @@ async fn main(ctx: Context) -> Result<()> { // Create a secure channel listener for Bob that will wait for requests to // initiate an Authenticated Key Exchange. - let secure_channel_listener = node - .create_secure_channel_listener( - &bob, - "bob_listener", - SecureChannelListenerOptions::new().as_consumer(listener.flow_control_id()), - ) - .await?; + let secure_channel_listener = node.create_secure_channel_listener( + &bob, + "bob_listener", + SecureChannelListenerOptions::new().as_consumer(listener.flow_control_id()), + )?; // Allow access to the Echoer via Secure Channels node.flow_controls() - .add_consumer("echoer", secure_channel_listener.flow_control_id()); + .add_consumer(&"echoer".into(), secure_channel_listener.flow_control_id()); - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-initiator.rs b/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-initiator.rs index 13258701155..f59fdeb3d9d 100644 --- a/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-initiator.rs +++ b/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-initiator.rs @@ -35,5 +35,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-middle.rs b/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-middle.rs index 71d80764cc6..5432413981c 100644 --- a/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-middle.rs +++ b/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-middle.rs @@ -26,12 +26,11 @@ async fn main(ctx: Context) -> Result<()> { node.start_worker( "forward_to_bob", Relay::new(route![udp_bind.clone(), (UDP, "127.0.0.1:4000")]), - ) - .await?; + )?; node.flow_controls() - .add_consumer("forward_to_bob", udp_bind.flow_control_id()); + .add_consumer(&"forward_to_bob".into(), udp_bind.flow_control_id()); - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-responder.rs b/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-responder.rs index 930731f514c..32075f950f6 100644 --- a/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-responder.rs +++ b/examples/rust/get_started/examples/05-secure-channel-over-two-udp-hops-responder.rs @@ -14,7 +14,7 @@ async fn main(ctx: Context) -> Result<()> { // Initialize the UDP Transport. let udp = node.create_udp_transport().await?; - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; let bob = node.create_identity().await?; @@ -27,18 +27,16 @@ async fn main(ctx: Context) -> Result<()> { // Create a secure channel listener for Bob that will wait for requests to // initiate an Authenticated Key Exchange. - let secure_channel_listener = node - .create_secure_channel_listener( - &bob, - "bob_listener", - SecureChannelListenerOptions::new().as_consumer(udp_bind.flow_control_id()), - ) - .await?; + let secure_channel_listener = node.create_secure_channel_listener( + &bob, + "bob_listener", + SecureChannelListenerOptions::new().as_consumer(udp_bind.flow_control_id()), + )?; // Allow access to the Echoer via Secure Channels node.flow_controls() - .add_consumer("echoer", secure_channel_listener.flow_control_id()); + .add_consumer(&"echoer".into(), secure_channel_listener.flow_control_id()); - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. Ok(()) } diff --git a/examples/rust/get_started/examples/06-credentials-exchange-client.rs b/examples/rust/get_started/examples/06-credentials-exchange-client.rs index 8ae51627c57..e242f56812a 100644 --- a/examples/rust/get_started/examples/06-credentials-exchange-client.rs +++ b/examples/rust/get_started/examples/06-credentials-exchange-client.rs @@ -1,11 +1,12 @@ use ockam::identity::{SecureChannelOptions, Vault}; -use ockam::tcp::{TcpConnectionOptions, TcpTransportExtension}; +use ockam::tcp::TcpConnectionOptions; use ockam::vault::{EdDSACurve25519SecretKey, SigningSecret, SoftwareVaultForSigning}; use ockam::{route, Context, Node, Result}; use ockam_api::enroll::enrollment::Enrollment; use ockam_api::nodes::NodeManager; use ockam_api::DefaultAddress; use ockam_multiaddr::MultiAddr; +use ockam_transport_tcp::TcpTransportExtension; #[ockam::node] async fn main(ctx: Context) -> Result<()> { @@ -24,9 +25,9 @@ async fn main(ctx: Context) -> Result<()> { let mut vault = Vault::create().await?; vault.identity_vault = identity_vault; - let mut node = Node::builder().await?.with_vault(vault).build(&ctx).await?; + let mut node = Node::builder().await?.with_vault(vault).build(&ctx)?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an Identity representing the client // We preload the client vault with a change history and secret key corresponding to the identity identifier @@ -88,5 +89,5 @@ async fn main(ctx: Context) -> Result<()> { .await?; println!("Received: {}", reply); // should print "Hello Ockam!" - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/06-credentials-exchange-issuer.rs b/examples/rust/get_started/examples/06-credentials-exchange-issuer.rs index dec2c46402e..6416eb4524d 100644 --- a/examples/rust/get_started/examples/06-credentials-exchange-issuer.rs +++ b/examples/rust/get_started/examples/06-credentials-exchange-issuer.rs @@ -29,7 +29,7 @@ async fn main(ctx: Context) -> Result<()> { let mut vault = Vault::create().await?; vault.identity_vault = identity_vault; - let node = Node::builder().await?.with_vault(vault).build(&ctx).await?; + let node = Node::builder().await?.with_vault(vault).build(&ctx)?; let issuer_identity = hex::decode("81825837830101583285f68200815820afbca9cf5d440147450f9f0d0a038a337b3fe5c17086163f2c54509558b62ef4f41a654cf97d1a7818fc7d8200815840650c4c939b96142546559aed99c52b64aa8a2f7b242b46534f7f8d0c5cc083d2c97210b93e9bca990e9cb9301acc2b634ffb80be314025f9adc870713e6fde0d").unwrap(); let issuer = node.import_private_identity(None, &issuer_identity, &secret).await?; @@ -87,27 +87,25 @@ async fn main(ctx: Context) -> Result<()> { // Start a secure channel listener that only allows channels where the identity // at the other end of the channel can authenticate with the latest private key // corresponding to one of the above known public identifiers. - node.create_secure_channel_listener(&issuer, DefaultAddress::SECURE_CHANNEL_LISTENER, sc_listener_options) - .await?; + node.create_secure_channel_listener(&issuer, DefaultAddress::SECURE_CHANNEL_LISTENER, sc_listener_options)?; // Start a credential issuer worker that will only accept incoming requests from // authenticated secure channels with our known public identifiers. let allow_known = IdentityIdAccessControl::new(known_identifiers); node.flow_controls() - .add_consumer(DefaultAddress::CREDENTIAL_ISSUER, &sc_listener_flow_control_id); + .add_consumer(&DefaultAddress::CREDENTIAL_ISSUER.into(), &sc_listener_flow_control_id); node.start_worker_with_access_control( DefaultAddress::CREDENTIAL_ISSUER, credential_issuer, allow_known, AllowAll, - ) - .await?; + )?; // Initialize TCP Transport, create a TCP listener, and wait for connections. - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; tcp.listen("127.0.0.1:5000", tcp_listener_options).await?; - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. println!("issuer started"); Ok(()) } diff --git a/examples/rust/get_started/examples/06-credentials-exchange-server.rs b/examples/rust/get_started/examples/06-credentials-exchange-server.rs index a44393728ea..beefd073114 100644 --- a/examples/rust/get_started/examples/06-credentials-exchange-server.rs +++ b/examples/rust/get_started/examples/06-credentials-exchange-server.rs @@ -28,10 +28,10 @@ async fn main(ctx: Context) -> Result<()> { let mut vault = Vault::create().await?; vault.identity_vault = identity_vault; - let node = Node::builder().await?.with_vault(vault).build(&ctx).await?; + let node = Node::builder().await?.with_vault(vault).build(&ctx)?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an Identity representing the server // Load an identity corresponding to the following public identifier @@ -81,7 +81,7 @@ async fn main(ctx: Context) -> Result<()> { .as_consumer(&tcp_listener_options.spawner_flow_control_id()); node.flow_controls().add_consumer( - DefaultAddress::ECHO_SERVICE, + &DefaultAddress::ECHO_SERVICE.into(), &sc_listener_options.spawner_flow_control_id(), ); let allow_production_incoming = IncomingAbac::create_name_value( @@ -96,25 +96,22 @@ async fn main(ctx: Context) -> Result<()> { Some(issuer), "cluster", "production", - ) - .await?; + )?; node.start_worker_with_access_control( DefaultAddress::ECHO_SERVICE, Echoer, allow_production_incoming, allow_production_outgoing, - ) - .await?; + )?; // Start a secure channel listener that only allows channels with // authenticated identities. - node.create_secure_channel_listener(&server, DefaultAddress::SECURE_CHANNEL_LISTENER, sc_listener_options) - .await?; + node.create_secure_channel_listener(&server, DefaultAddress::SECURE_CHANNEL_LISTENER, sc_listener_options)?; // Create a TCP listener and wait for incoming connections tcp.listen("127.0.0.1:4000", tcp_listener_options).await?; - // Don't call node.stop() here so this node runs forever. + // Don't call node.shutdown() here so this node runs forever. println!("server started"); Ok(()) } diff --git a/examples/rust/get_started/examples/11-attribute-based-authentication-control-plane.rs b/examples/rust/get_started/examples/11-attribute-based-authentication-control-plane.rs index bddca089016..7968f24f31d 100644 --- a/examples/rust/get_started/examples/11-attribute-based-authentication-control-plane.rs +++ b/examples/rust/get_started/examples/11-attribute-based-authentication-control-plane.rs @@ -14,7 +14,7 @@ use ockam_api::authenticator::enrollment_tokens::TokenAcceptor; use ockam_api::authenticator::one_time_code::OneTimeCode; use ockam_api::nodes::NodeManager; use ockam_api::{multiaddr_to_route, multiaddr_to_transport_route}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_multiaddr::MultiAddr; /// This node supports a "control" server on which several "edge" devices can connect @@ -54,7 +54,7 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime // Create a node with default implementations let node = node(ctx).await?; // Initialize the TCP transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an Identity for the control node let control_plane = node.create_identity().await?; @@ -79,7 +79,7 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime // Create a credential retriever that will be used to obtain credentials let credential_retriever = Arc::new(RemoteCredentialRetrieverCreator::new( - node.context().async_try_clone().await?, + node.context().try_clone()?, Arc::new(tcp.clone()), node.secure_channels(), RemoteCredentialRetrieverInfo::create_for_project_member( @@ -102,8 +102,7 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime Some(project.authority_identifier()), "component", "edge", - ) - .await?; + )?; // 4. create a tcp outlet with the above policy tcp.create_outlet( @@ -112,8 +111,7 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime TcpOutletOptions::new() .with_incoming_access_control_impl(incoming_access_control) .with_outgoing_access_control_impl(outgoing_access_control), - ) - .await?; + )?; // 5. create a relay on the Ockam orchestrator @@ -138,8 +136,7 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime // 6. create a secure channel listener which will allow the edge node to // start a secure channel when it is ready - node.create_secure_channel_listener(&control_plane, "untrusted", SecureChannelListenerOptions::new()) - .await?; + node.create_secure_channel_listener(&control_plane, "untrusted", SecureChannelListenerOptions::new())?; println!("created a secure channel listener"); // don't stop the node diff --git a/examples/rust/get_started/examples/11-attribute-based-authentication-edge-plane.rs b/examples/rust/get_started/examples/11-attribute-based-authentication-edge-plane.rs index 86bf872fc70..6eea50af119 100644 --- a/examples/rust/get_started/examples/11-attribute-based-authentication-edge-plane.rs +++ b/examples/rust/get_started/examples/11-attribute-based-authentication-edge-plane.rs @@ -11,7 +11,7 @@ use ockam_api::authenticator::one_time_code::OneTimeCode; use ockam_api::nodes::NodeManager; use ockam_api::{multiaddr_to_route, multiaddr_to_transport_route}; use ockam_core::compat::sync::Arc; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_multiaddr::MultiAddr; use ockam_transport_tcp::{TcpInletOptions, TcpTransportExtension}; @@ -51,7 +51,7 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime // Create a node with default implementations let node = node(ctx).await?; // Use the TCP transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an Identity for the edge plane let edge_plane = node.create_identity().await?; @@ -77,7 +77,7 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime // Create a credential retriever that will be used to obtain credentials let credential_retriever = Arc::new(RemoteCredentialRetrieverCreator::new( - node.context().async_try_clone().await?, + node.context().try_clone()?, Arc::new(tcp.clone()), node.secure_channels(), RemoteCredentialRetrieverInfo::create_for_project_member( @@ -100,8 +100,7 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime Some(project.authority_identifier()), "component", "control", - ) - .await?; + )?; // 4. create a tcp inlet with the above policy diff --git a/examples/rust/get_started/examples/alice.rs b/examples/rust/get_started/examples/alice.rs index 804da2cbc8c..ec7418eb844 100644 --- a/examples/rust/get_started/examples/alice.rs +++ b/examples/rust/get_started/examples/alice.rs @@ -8,7 +8,7 @@ async fn main(ctx: Context) -> Result<()> { // Create a node with default implementations let mut node = node(ctx).await?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create an Identity to represent Alice. let alice = node.create_identity().await?; diff --git a/examples/rust/get_started/examples/bob.rs b/examples/rust/get_started/examples/bob.rs index d45a0faf64a..6be42251b30 100644 --- a/examples/rust/get_started/examples/bob.rs +++ b/examples/rust/get_started/examples/bob.rs @@ -14,7 +14,7 @@ impl Worker for Echoer { type Message = String; async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { - println!("\n[✓] Address: {}, Received: {:?}", ctx.address(), msg); + println!("\n[✓] Address: {}, Received: {:?}", ctx.primary_address(), msg); // Echo the message body back on its return_route. ctx.send(msg.return_route().clone(), msg.into_body()?).await @@ -26,22 +26,21 @@ async fn main(ctx: Context) -> Result<()> { // Create a node with default implementations let node = node(ctx).await?; // Initialize the TCP Transport - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Start a worker, of type Echoer, at address "echoer". // This worker will echo back every message it receives, along its return route. let sc_options = SecureChannelListenerOptions::new(); - node.start_worker("echoer", Echoer).await?; + node.start_worker("echoer", Echoer)?; node.flow_controls() - .add_consumer("echoer", &sc_options.spawner_flow_control_id()); + .add_consumer(&"echoer".into(), &sc_options.spawner_flow_control_id()); // Create an Identity to represent Bob. let bob = node.create_identity().await?; // Create a secure channel listener for Bob that will wait for requests to // initiate an Authenticated Key Exchange. - node.create_secure_channel_listener(&bob, "listener", sc_options) - .await?; + node.create_secure_channel_listener(&bob, "listener", sc_options)?; // The computer that is running this program is likely within a private network and // not accessible over the internet. @@ -62,6 +61,6 @@ async fn main(ctx: Context) -> Result<()> { println!("Forwarding address for Bob is:"); println!("{}", relay.remote_address()); - // We won't call ctx.stop() here, this program will run until you stop it with Ctrl-C + // We won't call ctx.shutdown_node() here, this program will run until you stop it with Ctrl-C Ok(()) } diff --git a/examples/rust/get_started/examples/hello.rs b/examples/rust/get_started/examples/hello.rs index 4ce82c2292d..107b538c5cf 100644 --- a/examples/rust/get_started/examples/hello.rs +++ b/examples/rust/get_started/examples/hello.rs @@ -12,7 +12,7 @@ async fn main(ctx: Context) -> Result<()> { // initiate an Authenticated Key Exchange. let options = SecureChannelListenerOptions::new(); let sc_flow_control_id = options.spawner_flow_control_id(); - node.create_secure_channel_listener(&bob, "bob", options).await?; + node.create_secure_channel_listener(&bob, "bob", options)?; // Create an entity to represent Alice. let alice = node.create_identity().await?; @@ -28,7 +28,7 @@ async fn main(ctx: Context) -> Result<()> { // // This message will automatically get encrypted when it enters the channel // and decrypted just before it exits the channel. - node.flow_controls().add_consumer("app", &sc_flow_control_id); + node.flow_controls().add_consumer(&"app".into(), &sc_flow_control_id); node.send(route![channel, "app"], "Hello Ockam!".to_string()).await?; // Wait to receive a message for the "app" worker and print it. @@ -36,5 +36,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", message.into_body()?); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/examples/vault-and-identities.rs b/examples/rust/get_started/examples/vault-and-identities.rs index 36e3adaf5ca..b3285524dd8 100644 --- a/examples/rust/get_started/examples/vault-and-identities.rs +++ b/examples/rust/get_started/examples/vault-and-identities.rs @@ -10,5 +10,5 @@ async fn main(ctx: Context) -> Result<()> { let _alice = node.create_identity().await?; // Stop the node. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/get_started/src/echoer.rs b/examples/rust/get_started/src/echoer.rs index 578ef57c2c5..6dac38aa74f 100644 --- a/examples/rust/get_started/src/echoer.rs +++ b/examples/rust/get_started/src/echoer.rs @@ -8,7 +8,7 @@ impl Worker for Echoer { type Message = String; async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { - println!("Address: {}, Received: {:?}", ctx.address(), msg); + println!("Address: {}, Received: {:?}", ctx.primary_address(), msg); // Echo the message body back on its return_route. ctx.send(msg.return_route().clone(), msg.into_body()?).await diff --git a/examples/rust/get_started/src/hop.rs b/examples/rust/get_started/src/hop.rs index 7f2bdac44f5..727dee397fc 100644 --- a/examples/rust/get_started/src/hop.rs +++ b/examples/rust/get_started/src/hop.rs @@ -10,10 +10,10 @@ impl Worker for Hop { /// This handle function takes any incoming message and forwards /// it to the next hop in it's onward route async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { - println!("Address: {}, Received: {:?}", ctx.address(), msg); + println!("Address: {}, Received: {:?}", ctx.primary_address(), msg); // Send the message to the next worker on its onward_route - ctx.forward(msg.into_local_message().step_forward(&ctx.address())?) + ctx.forward(msg.into_local_message().step_forward(ctx.primary_address().clone())?) .await } } diff --git a/examples/rust/get_started/src/logger.rs b/examples/rust/get_started/src/logger.rs index 96817597bc0..0d47b5f3468 100644 --- a/examples/rust/get_started/src/logger.rs +++ b/examples/rust/get_started/src/logger.rs @@ -12,14 +12,19 @@ impl Worker for Logger { /// the message to the next hop in it's onward route async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { let local_msg = msg.into_local_message(); - let payload = local_msg.payload_ref(); + let payload = local_msg.payload(); if let Ok(str) = String::from_utf8(payload.to_vec()) { - println!("Address: {}, Received string: {}", ctx.address(), str); + println!("Address: {}, Received string: {}", ctx.primary_address(), str); } else { - println!("Address: {}, Received binary: {}", ctx.address(), hex::encode(payload)); + println!( + "Address: {}, Received binary: {}", + ctx.primary_address(), + hex::encode(payload) + ); } - ctx.forward(local_msg.step_forward(&ctx.address())?).await + ctx.forward(local_msg.step_forward(ctx.primary_address().clone())?) + .await } } diff --git a/examples/rust/get_started/src/relay.rs b/examples/rust/get_started/src/relay.rs index 3f3a32cf0f7..75637e96b0c 100644 --- a/examples/rust/get_started/src/relay.rs +++ b/examples/rust/get_started/src/relay.rs @@ -24,7 +24,7 @@ impl Worker for Relay { /// This handle function takes any incoming message and forwards /// it to the next hop in it's onward route async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { - println!("Address: {}, Received: {:?}", ctx.address(), msg); + println!("Address: {}, Received: {:?}", ctx.primary_address(), msg); let next_on_route = self.route.next()?.clone(); @@ -32,7 +32,7 @@ impl Worker for Relay { let mut local_message = msg.into_local_message(); local_message = local_message.pop_front_onward_route()?; - local_message = local_message.prepend_front_onward_route(&self.route); // Prepend predefined route to the onward_route + local_message = local_message.prepend_front_onward_route(self.route.clone()); // Prepend predefined route to the onward_route let prev_hop = local_message.return_route().next()?.clone(); @@ -40,12 +40,11 @@ impl Worker for Relay { .flow_controls() .find_flow_control_with_producer_address(&next_on_route) { - ctx.flow_controls() - .add_consumer(prev_hop.clone(), info.flow_control_id()); + ctx.flow_controls().add_consumer(&prev_hop, info.flow_control_id()); } if let Some(info) = ctx.flow_controls().find_flow_control_with_producer_address(&prev_hop) { - ctx.flow_controls().add_consumer(next_on_route, info.flow_control_id()); + ctx.flow_controls().add_consumer(&next_on_route, info.flow_control_id()); } // Send the message on its onward_route diff --git a/examples/rust/mitm_node/src/bin/tcp_mitm.rs b/examples/rust/mitm_node/src/bin/tcp_mitm.rs index 09a981eb589..0f8c7d39d1e 100644 --- a/examples/rust/mitm_node/src/bin/tcp_mitm.rs +++ b/examples/rust/mitm_node/src/bin/tcp_mitm.rs @@ -1,12 +1,12 @@ use mitm_node::tcp_interceptor::{ProcessorInfo, Role, TcpMitmTransport}; use ockam::{Context, Result}; -use ockam_core::{route, Address, AsyncTryClone, TransportMessage}; +use ockam_core::{route, Address, TransportMessage, TryClone}; use ockam_transport_core::encode_transport_message; use std::time::Duration; use tokio::io::AsyncWriteExt; use tracing::info; -#[derive(AsyncTryClone)] +#[derive(TryClone)] struct MitmMonitor { tcp_mitm: TcpMitmTransport, } @@ -38,7 +38,7 @@ impl MitmMonitor { // Attach to the intercepted tcp connection async fn query_processor(&self, processor: ProcessorInfo) -> Result<()> { - let self_clone = self.async_try_clone().await?; + let self_clone = self.try_clone()?; tokio::spawn(async move { self_clone.send_malicious_message(&processor).await }) .await .unwrap() @@ -79,7 +79,7 @@ async fn main(ctx: Context) -> Result<()> { let port1 = "4015"; let port2 = "4016"; - let tcp_mitm = TcpMitmTransport::create(&ctx).await?; + let tcp_mitm = TcpMitmTransport::create(&ctx)?; tcp_mitm .listen(format!("{}:{}", listen_ip, port1), format!("{}:{}", target_ip, port1)) diff --git a/examples/rust/mitm_node/src/tcp_interceptor/transport/lifecycle.rs b/examples/rust/mitm_node/src/tcp_interceptor/transport/lifecycle.rs index 7db8ec00959..925e4afb597 100644 --- a/examples/rust/mitm_node/src/tcp_interceptor/transport/lifecycle.rs +++ b/examples/rust/mitm_node/src/tcp_interceptor/transport/lifecycle.rs @@ -1,12 +1,12 @@ -use ockam_core::{AsyncTryClone, Result}; +use ockam_core::{Result, TryClone}; use ockam_node::Context; use crate::tcp_interceptor::{TcpMitmRegistry, TcpMitmTransport}; impl TcpMitmTransport { - pub async fn create(ctx: &Context) -> Result { + pub fn create(ctx: &Context) -> Result { let tcp = Self { - ctx: ctx.async_try_clone().await?, + ctx: ctx.try_clone()?, registry: Default::default(), }; Ok(tcp) diff --git a/examples/rust/mitm_node/src/tcp_interceptor/transport/listener.rs b/examples/rust/mitm_node/src/tcp_interceptor/transport/listener.rs index 4e0b6eb35fa..953cf39af45 100644 --- a/examples/rust/mitm_node/src/tcp_interceptor/transport/listener.rs +++ b/examples/rust/mitm_node/src/tcp_interceptor/transport/listener.rs @@ -1,7 +1,7 @@ use crate::tcp_interceptor::transport::common::parse_socket_addr; use crate::tcp_interceptor::{TcpMitmListenProcessor, TcpMitmTransport}; use ockam_core::compat::net::SocketAddr; -use ockam_core::{Address, AsyncTryClone, Result}; +use ockam_core::{Address, Result, TryClone}; impl TcpMitmTransport { pub async fn listen( @@ -16,7 +16,7 @@ impl TcpMitmTransport { &self.ctx, self.registry.clone(), bind_addr, - self.async_try_clone().await?, + self.try_clone()?, target_addr, ) .await?; @@ -25,7 +25,7 @@ impl TcpMitmTransport { } /// Interrupt an active TCP listener given its `Address` - pub async fn stop_listener(&self, address: &Address) -> Result<()> { - self.ctx.stop_processor(address.clone()).await + pub fn stop_listener(&self, address: &Address) -> Result<()> { + self.ctx.stop_address(address) } } diff --git a/examples/rust/mitm_node/src/tcp_interceptor/transport/mod.rs b/examples/rust/mitm_node/src/tcp_interceptor/transport/mod.rs index d2bd081f921..f14762c4b91 100644 --- a/examples/rust/mitm_node/src/tcp_interceptor/transport/mod.rs +++ b/examples/rust/mitm_node/src/tcp_interceptor/transport/mod.rs @@ -3,11 +3,11 @@ mod lifecycle; mod listener; use crate::tcp_interceptor::TcpMitmRegistry; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_node::Context; -#[derive(AsyncTryClone)] -#[async_try_clone(crate = "ockam_core")] +#[derive(TryClone)] +#[try_clone(crate = "ockam_core")] pub struct TcpMitmTransport { ctx: Context, registry: TcpMitmRegistry, diff --git a/examples/rust/mitm_node/src/tcp_interceptor/workers/listener.rs b/examples/rust/mitm_node/src/tcp_interceptor/workers/listener.rs index 245785a65c9..a37dc8827ee 100644 --- a/examples/rust/mitm_node/src/tcp_interceptor/workers/listener.rs +++ b/examples/rust/mitm_node/src/tcp_interceptor/workers/listener.rs @@ -1,4 +1,4 @@ -use crate::tcp_interceptor::{Role, TcpMitmProcessor, TcpMitmRegistry, TcpMitmTransport, CLUSTER_NAME}; +use crate::tcp_interceptor::{Role, TcpMitmProcessor, TcpMitmRegistry, TcpMitmTransport}; use ockam_core::{async_trait, compat::net::SocketAddr}; use ockam_core::{Address, Processor, Result}; use ockam_node::Context; @@ -34,7 +34,7 @@ impl TcpMitmListenProcessor { target_addr, }; - ctx.start_processor(address.clone(), processor).await?; + ctx.start_processor(address.clone(), processor)?; Ok((saddr, address)) } @@ -45,15 +45,13 @@ impl Processor for TcpMitmListenProcessor { type Context = Context; async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(CLUSTER_NAME).await?; - - self.registry.add_listener(&ctx.address()); + self.registry.add_listener(ctx.primary_address()); Ok(()) } async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.registry.remove_listener(&ctx.address()); + self.registry.remove_listener(ctx.primary_address()); Ok(()) } @@ -82,8 +80,7 @@ impl Processor for TcpMitmListenProcessor { target_read_half, write_half, self.registry.clone(), - ) - .await?; + )?; // Forward from the source connection to the target TcpMitmProcessor::start( @@ -94,8 +91,7 @@ impl Processor for TcpMitmListenProcessor { read_half, target_write_half, self.registry.clone(), - ) - .await?; + )?; Ok(true) } diff --git a/examples/rust/mitm_node/src/tcp_interceptor/workers/processor.rs b/examples/rust/mitm_node/src/tcp_interceptor/workers/processor.rs index a558b294098..56bd34894a9 100644 --- a/examples/rust/mitm_node/src/tcp_interceptor/workers/processor.rs +++ b/examples/rust/mitm_node/src/tcp_interceptor/workers/processor.rs @@ -1,4 +1,4 @@ -use crate::tcp_interceptor::{Role, TcpMitmRegistry, CLUSTER_NAME}; +use crate::tcp_interceptor::{Role, TcpMitmRegistry}; use ockam_core::compat::sync::Arc; use ockam_core::{async_trait, Address, AllowAll}; use ockam_core::{Processor, Result}; @@ -34,7 +34,7 @@ impl TcpMitmProcessor { } } - pub async fn start( + pub fn start( ctx: &Context, role: Role, address: Address, @@ -47,8 +47,7 @@ impl TcpMitmProcessor { let receiver = Self::new(address_of_other_processor, role, read_half, write_half, registry); - ctx.start_processor_with_access_control(address, receiver, AllowAll, AllowAll) - .await?; + ctx.start_processor_with_access_control(address, receiver, AllowAll, AllowAll)?; Ok(()) } @@ -59,20 +58,18 @@ impl Processor for TcpMitmProcessor { type Context = Context; async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(CLUSTER_NAME).await?; - self.registry - .add_processor(&ctx.address(), self.role, self.write_half.clone()); + .add_processor(ctx.primary_address(), self.role, self.write_half.clone()); - debug!("Initialize {}", ctx.address()); + debug!("Initialize {}", ctx.primary_address()); Ok(()) } async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.registry.remove_processor(&ctx.address()); + self.registry.remove_processor(ctx.primary_address()); - debug!("Shutdown {}", ctx.address()); + debug!("Shutdown {}", ctx.primary_address()); Ok(()) } @@ -83,9 +80,9 @@ impl Processor for TcpMitmProcessor { let len = match self.read_half.read(&mut buf).await { Ok(l) if l != 0 => l, _ => { - info!("Connection was closed; dropping stream {}", ctx.address()); + info!("Connection was closed; dropping stream {}", ctx.primary_address()); - let _ = ctx.stop_processor(self.address_of_other_processor.clone()).await; + let _ = ctx.stop_address(&self.address_of_other_processor); return Ok(false); } @@ -93,12 +90,12 @@ impl Processor for TcpMitmProcessor { match self.write_half.lock().await.write_all(&buf[..len]).await { Ok(_) => { - debug!("Forwarded {} bytes from {}", len, ctx.address()); + debug!("Forwarded {} bytes from {}", len, ctx.primary_address()); } _ => { - debug!("Connection was closed; dropping stream {}", ctx.address()); + debug!("Connection was closed; dropping stream {}", ctx.primary_address()); - let _ = ctx.stop_processor(self.address_of_other_processor.clone()).await; + let _ = ctx.stop_address(&self.address_of_other_processor); return Ok(false); } diff --git a/examples/rust/no_std/examples/01-node.rs b/examples/rust/no_std/examples/01-node.rs index c7661892a67..54f1b42c0df 100644 --- a/examples/rust/no_std/examples/01-node.rs +++ b/examples/rust/no_std/examples/01-node.rs @@ -63,5 +63,5 @@ async fn main(ctx: Context) -> Result<()> { // Stop the node as soon as it starts. info!("Stop the node as soon as it starts."); - node.stop().await; + node.shutdown().await; } diff --git a/examples/rust/no_std/examples/hello.rs b/examples/rust/no_std/examples/hello.rs index 60f69ceeeee..7c1fa996e00 100644 --- a/examples/rust/no_std/examples/hello.rs +++ b/examples/rust/no_std/examples/hello.rs @@ -102,5 +102,5 @@ async fn main(ctx: Context) -> Result<()> { } // Stop all workers, stop the node, cleanup and return. - node.stop().await + node.shutdown().await } diff --git a/examples/rust/rendezvous/src/bin/client.rs b/examples/rust/rendezvous/src/bin/client.rs index ce3e5b539f4..36cf7f168a3 100644 --- a/examples/rust/rendezvous/src/bin/client.rs +++ b/examples/rust/rendezvous/src/bin/client.rs @@ -5,7 +5,7 @@ use ockam_transport_udp::{UdpBindArguments, UdpBindOptions, UdpTransport, UDP}; #[ockam_macros::node] async fn main(ctx: Context) -> Result<()> { - let udp = UdpTransport::create(&ctx).await?; + let udp = UdpTransport::create(&ctx)?; let bind = udp .bind(UdpBindArguments::new(), UdpBindOptions::new()) @@ -19,5 +19,5 @@ async fn main(ctx: Context) -> Result<()> { println!("App Received: {}", reply); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - ctx.stop().await + ctx.shutdown_node().await } diff --git a/examples/rust/rendezvous/src/bin/echo_server.rs b/examples/rust/rendezvous/src/bin/echo_server.rs index f86e8a20c74..64fa8ea5d36 100644 --- a/examples/rust/rendezvous/src/bin/echo_server.rs +++ b/examples/rust/rendezvous/src/bin/echo_server.rs @@ -5,7 +5,7 @@ use ockam_transport_udp::{UdpBindArguments, UdpBindOptions, UdpTransport}; #[ockam_macros::node] async fn main(ctx: Context) -> Result<()> { - let udp = UdpTransport::create(&ctx).await?; + let udp = UdpTransport::create(&ctx)?; let bind = udp .bind( UdpBindArguments::new().with_bind_address("127.0.0.1:8000")?, @@ -13,10 +13,10 @@ async fn main(ctx: Context) -> Result<()> { ) .await?; - ctx.start_worker("echoer", Echoer).await?; + ctx.start_worker("echoer", Echoer)?; ctx.flow_controls() - .add_consumer("echoer", bind.flow_control_id()); + .add_consumer(&"echoer".into(), bind.flow_control_id()); Ok(()) } diff --git a/examples/rust/tcp_inlet_and_outlet/examples/01-inlet-outlet.rs b/examples/rust/tcp_inlet_and_outlet/examples/01-inlet-outlet.rs index 4c6379f68a1..e7e75721a3b 100644 --- a/examples/rust/tcp_inlet_and_outlet/examples/01-inlet-outlet.rs +++ b/examples/rust/tcp_inlet_and_outlet/examples/01-inlet-outlet.rs @@ -5,7 +5,7 @@ use ockam::{node, route, Context, Result}; async fn main(ctx: Context) -> Result<()> { // Initialize the TCP Transport. let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Expect second command line argument to be the TCP address of a target TCP server. // For example: 127.0.0.1:4002 @@ -24,8 +24,7 @@ async fn main(ctx: Context) -> Result<()> { // a previous message from the Inlet. let outlet_target = std::env::args().nth(2).expect("no outlet target given"); - tcp.create_outlet("outlet", outlet_target.try_into()?, TcpOutletOptions::new()) - .await?; + tcp.create_outlet("outlet", outlet_target.try_into()?, TcpOutletOptions::new())?; // Expect first command line argument to be the TCP address on which to start an Inlet // For example: 127.0.0.1:4001 @@ -45,7 +44,7 @@ async fn main(ctx: Context) -> Result<()> { tcp.create_inlet(inlet_address, route!["outlet"], TcpInletOptions::new()) .await?; - // We won't call ctx.stop() here, + // We won't call ctx.shutdown_node() here, // so this program will keep running until you interrupt it with Ctrl-C. Ok(()) } diff --git a/examples/rust/tcp_inlet_and_outlet/examples/02-inlet.rs b/examples/rust/tcp_inlet_and_outlet/examples/02-inlet.rs index 4c6dce340e7..3b4eef6bf87 100644 --- a/examples/rust/tcp_inlet_and_outlet/examples/02-inlet.rs +++ b/examples/rust/tcp_inlet_and_outlet/examples/02-inlet.rs @@ -5,7 +5,7 @@ use ockam::{node, route, Context, Result}; async fn main(ctx: Context) -> Result<()> { // Initialize the TCP Transport. let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // We know that the Outlet node is listening for Ockam Routing Messages // over TCP and is running at Ockam Worker address "outlet". @@ -37,7 +37,7 @@ async fn main(ctx: Context) -> Result<()> { tcp.create_inlet(inlet_address, route_to_outlet, TcpInletOptions::new()) .await?; - // We won't call ctx.stop() here, + // We won't call ctx.shutdown_node() here, // so this program will keep running until you interrupt it with Ctrl-C. Ok(()) } diff --git a/examples/rust/tcp_inlet_and_outlet/examples/02-outlet.rs b/examples/rust/tcp_inlet_and_outlet/examples/02-outlet.rs index d3ad2ba8631..30902132753 100644 --- a/examples/rust/tcp_inlet_and_outlet/examples/02-outlet.rs +++ b/examples/rust/tcp_inlet_and_outlet/examples/02-outlet.rs @@ -5,7 +5,7 @@ use ockam::{node, Context, Result}; async fn main(ctx: Context) -> Result<()> { // Initialize the TCP Transport. let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Expect first command line argument to be the TCP address of a target TCP server. // For example: 127.0.0.1:4002 @@ -30,8 +30,7 @@ async fn main(ctx: Context) -> Result<()> { "outlet", outlet_target.try_into()?, TcpOutletOptions::new().as_consumer(&tcp_listener_options.spawner_flow_control_id()), - ) - .await?; + )?; // Create a TCP listener to receive Ockam Routing Messages from other ockam nodes. // @@ -40,7 +39,7 @@ async fn main(ctx: Context) -> Result<()> { let port = std::env::args().nth(2).unwrap_or_else(|| "4000".to_string()); tcp.listen(format!("127.0.0.1:{port}"), tcp_listener_options).await?; - // We won't call ctx.stop() here, + // We won't call ctx.shutdown_node() here, // so this program will keep running until you interrupt it with Ctrl-C. Ok(()) } diff --git a/examples/rust/tcp_inlet_and_outlet/examples/03-inlet.rs b/examples/rust/tcp_inlet_and_outlet/examples/03-inlet.rs index 36c7430cb63..9f6e86c8d7e 100644 --- a/examples/rust/tcp_inlet_and_outlet/examples/03-inlet.rs +++ b/examples/rust/tcp_inlet_and_outlet/examples/03-inlet.rs @@ -6,7 +6,7 @@ use ockam::{node, route, Context, Result}; async fn main(ctx: Context) -> Result<()> { // Initialize the TCP Transport. let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; let e = node.create_identity().await?; let outlet_port = std::env::args().nth(2).unwrap_or_else(|| "4000".to_string()); @@ -48,7 +48,7 @@ async fn main(ctx: Context) -> Result<()> { tcp.create_inlet(inlet_address, route_to_outlet, TcpInletOptions::new()) .await?; - // We won't call ctx.stop() here, + // We won't call ctx.shutdown_node() here, // so this program will keep running until you interrupt it with Ctrl-C. Ok(()) } diff --git a/examples/rust/tcp_inlet_and_outlet/examples/03-outlet.rs b/examples/rust/tcp_inlet_and_outlet/examples/03-outlet.rs index cca1c5226d3..7558cee9e9d 100644 --- a/examples/rust/tcp_inlet_and_outlet/examples/03-outlet.rs +++ b/examples/rust/tcp_inlet_and_outlet/examples/03-outlet.rs @@ -6,7 +6,7 @@ use ockam::{node, Context, Result}; async fn main(ctx: Context) -> Result<()> { // Initialize the TCP Transport. let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create: // 1. An Identity to represent this Node @@ -19,8 +19,7 @@ async fn main(ctx: Context) -> Result<()> { let secure_channel_listener_options = SecureChannelListenerOptions::new().as_consumer(&tcp_listener_options.spawner_flow_control_id()); let secure_channel_flow_control_id = secure_channel_listener_options.spawner_flow_control_id(); - node.create_secure_channel_listener(&e, "secure_channel_listener", secure_channel_listener_options) - .await?; + node.create_secure_channel_listener(&e, "secure_channel_listener", secure_channel_listener_options)?; // Expect first command line argument to be the TCP address of a target TCP server. // For example: 127.0.0.1:4002 @@ -43,8 +42,7 @@ async fn main(ctx: Context) -> Result<()> { "outlet", outlet_target.try_into()?, TcpOutletOptions::new().as_consumer(&secure_channel_flow_control_id), - ) - .await?; + )?; // Create a TCP listener to receive Ockam Routing Messages from other ockam nodes. // @@ -53,7 +51,7 @@ async fn main(ctx: Context) -> Result<()> { let port = std::env::args().nth(2).unwrap_or_else(|| "4000".to_string()); tcp.listen(format!("127.0.0.1:{port}"), tcp_listener_options).await?; - // We won't call ctx.stop() here, + // We won't call ctx.shutdown_node() here, // so this program will keep running until you interrupt it with Ctrl-C. Ok(()) } diff --git a/examples/rust/tcp_inlet_and_outlet/examples/04-inlet.rs b/examples/rust/tcp_inlet_and_outlet/examples/04-inlet.rs index b409978db18..efed8a895df 100644 --- a/examples/rust/tcp_inlet_and_outlet/examples/04-inlet.rs +++ b/examples/rust/tcp_inlet_and_outlet/examples/04-inlet.rs @@ -6,7 +6,7 @@ use ockam::{node, route, Context, Result, Route}; async fn main(ctx: Context) -> Result<()> { // Initialize the TCP Transport. let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; // Create a Vault to store our cryptographic keys and an Identity to represent this Node. // Then initiate a handshake with the secure channel listener on the node that has the @@ -47,7 +47,7 @@ async fn main(ctx: Context) -> Result<()> { tcp.create_inlet(inlet_address, route_to_outlet, TcpInletOptions::new()) .await?; - // We won't call ctx.stop() here, + // We won't call ctx.shutdown_node() here, // so this program will keep running until you interrupt it with Ctrl-C. Ok(()) } diff --git a/examples/rust/tcp_inlet_and_outlet/examples/04-outlet.rs b/examples/rust/tcp_inlet_and_outlet/examples/04-outlet.rs index d8a3cf53a64..7ce978e6e29 100644 --- a/examples/rust/tcp_inlet_and_outlet/examples/04-outlet.rs +++ b/examples/rust/tcp_inlet_and_outlet/examples/04-outlet.rs @@ -7,7 +7,7 @@ use ockam::{node, Context, Result}; async fn main(ctx: Context) -> Result<()> { // Initialize the TCP Transport. let node = node(ctx).await?; - let tcp = node.create_tcp_transport().await?; + let tcp = node.create_tcp_transport()?; let e = node.create_identity().await?; @@ -16,8 +16,7 @@ async fn main(ctx: Context) -> Result<()> { let secure_channel_listener_options = SecureChannelListenerOptions::new().as_consumer(&tcp_flow_control_id); let secure_channel_flow_control_id = secure_channel_listener_options.spawner_flow_control_id(); - node.create_secure_channel_listener(&e, "secure_channel_listener", secure_channel_listener_options) - .await?; + node.create_secure_channel_listener(&e, "secure_channel_listener", secure_channel_listener_options)?; // Expect first command line argument to be the TCP address of a target TCP server. // For example: 127.0.0.1:4002 @@ -40,8 +39,7 @@ async fn main(ctx: Context) -> Result<()> { "outlet", outlet_target.try_into()?, TcpOutletOptions::new().as_consumer(&secure_channel_flow_control_id), - ) - .await?; + )?; // To allow Inlet Node and others to initiate an end-to-end secure channel with this program // we connect with 1.node.ockam.network:4000 as a TCP client and ask the forwarding @@ -57,7 +55,7 @@ async fn main(ctx: Context) -> Result<()> { println!("Forwarding address in Hub is:"); println!("{}", relay.remote_address()); - // We won't call ctx.stop() here, + // We won't call ctx.shutdown_node() here, // so this program will keep running until you interrupt it with Ctrl-C. Ok(()) } diff --git a/implementations/rust/ockam/ockam/src/lib.rs b/implementations/rust/ockam/ockam/src/lib.rs index 7c34dffb9c6..e867230ed44 100644 --- a/implementations/rust/ockam/ockam/src/lib.rs +++ b/implementations/rust/ockam/ockam/src/lib.rs @@ -66,9 +66,8 @@ pub use ockam_core::processor; /// may be changed in the future to a [`Worker`](crate::Worker)-specific macro. pub use ockam_core::worker; pub use ockam_core::{ - allow, deny, errcode, route, Address, Any, AsyncTryClone, Encoded, Error, LocalMessage, - Mailbox, Mailboxes, Message, Processor, ProtocolId, Result, Route, Routed, TransportMessage, - Worker, + allow, deny, errcode, route, Address, Any, Encoded, Error, LocalMessage, Mailbox, Mailboxes, + Message, Processor, ProtocolId, Result, Route, Routed, TransportMessage, TryClone, Worker, }; pub use ockam_identity as identity; // --- diff --git a/implementations/rust/ockam/ockam/src/node.rs b/implementations/rust/ockam/ockam/src/node.rs index 7e1b435e0aa..fc3a637e46b 100644 --- a/implementations/rust/ockam/ockam/src/node.rs +++ b/implementations/rust/ockam/ockam/src/node.rs @@ -2,8 +2,8 @@ use ockam_core::compat::string::String; use ockam_core::compat::sync::Arc; use ockam_core::flow_control::FlowControls; use ockam_core::{ - Address, AsyncTryClone, IncomingAccessControl, Message, OutgoingAccessControl, Processor, - Result, Route, Routed, Worker, + Address, IncomingAccessControl, Message, OutgoingAccessControl, Processor, Result, Route, + Routed, TryClone, Worker, }; use ockam_identity::{ CredentialRepository, IdentitiesAttributes, IdentitiesVerification, @@ -46,8 +46,7 @@ pub struct Node { /// let node = Node::builder() /// .await? /// .with_secrets_repository(Arc::new(SecretsSqlxDatabase::create().await?)) -/// .build(&ctx) -/// .await?; +/// .build(&ctx)?; /// Ok(node) /// } /// @@ -135,15 +134,18 @@ impl Node { } /// Spawns a SecureChannel listener at given `Address` with given [`SecureChannelListenerOptions`] - pub async fn create_secure_channel_listener( + pub fn create_secure_channel_listener( &self, identifier: &Identifier, address: impl Into
, options: impl Into, ) -> Result { - self.secure_channels() - .create_secure_channel_listener(self.get_context(), identifier, address, options) - .await + self.secure_channels().create_secure_channel_listener( + self.get_context(), + identifier, + address, + options, + ) } /// Initiate a SecureChannel using `Route` to the SecureChannel listener and [`SecureChannelOptions`] @@ -159,15 +161,15 @@ impl Node { } /// Start a new worker instance at the given address. Default Access Control is AllowAll - pub async fn start_worker(&self, address: impl Into
, worker: W) -> Result<()> + pub fn start_worker(&self, address: impl Into
, worker: W) -> Result<()> where W: Worker, { - self.context.start_worker(address, worker).await + self.context.start_worker(address, worker) } /// Start a new worker instance at the given address with given Access Controls - pub async fn start_worker_with_access_control( + pub fn start_worker_with_access_control( &self, address: impl Into
, worker: W, @@ -179,19 +181,18 @@ impl Node { { self.context .start_worker_with_access_control(address, worker, incoming, outgoing) - .await } /// Start a new processor instance at the given address. Default Access Control is DenyAll - pub async fn start_processor

(&self, address: impl Into

, processor: P) -> Result<()> + pub fn start_processor

(&self, address: impl Into

, processor: P) -> Result<()> where P: Processor, { - self.context.start_processor(address, processor).await + self.context.start_processor(address, processor) } /// Start a new processor instance at the given address with given Access Controls - pub async fn start_processor_with_access_control

( + pub fn start_processor_with_access_control

( &self, address: impl Into

, processor: P, @@ -203,12 +204,11 @@ impl Node { { self.context .start_processor_with_access_control(address, processor, incoming, outgoing) - .await } /// Signal to the local runtime to shut down - pub async fn stop(&mut self) -> Result<()> { - self.context.stop().await + pub async fn shutdown(&mut self) -> Result<()> { + self.context.shutdown_node().await } /// Send a message to an address or via a fully-qualified route @@ -384,9 +384,9 @@ impl NodeBuilder { } /// Build top level services - pub async fn build(self, ctx: &Context) -> Result { + pub fn build(self, ctx: &Context) -> Result { Ok(Node { - context: ctx.async_try_clone().await?, + context: ctx.try_clone()?, secure_channels: self.builder.build(), }) } diff --git a/implementations/rust/ockam/ockam/src/relay_service/options.rs b/implementations/rust/ockam/ockam/src/relay_service/options.rs index 385c7e7e32b..5b1330545c1 100644 --- a/implementations/rust/ockam/ockam/src/relay_service/options.rs +++ b/implementations/rust/ockam/ockam/src/relay_service/options.rs @@ -117,7 +117,7 @@ impl RelayServiceOptions { address: &Address, ) { for id in &self.consumer_service { - flow_controls.add_consumer(address.clone(), id); + flow_controls.add_consumer(address, id); } } @@ -127,7 +127,7 @@ impl RelayServiceOptions { address: &Address, ) { for id in &self.consumer_relay { - flow_controls.add_consumer(address.clone(), id); + flow_controls.add_consumer(address, id); } } } diff --git a/implementations/rust/ockam/ockam/src/relay_service/relay.rs b/implementations/rust/ockam/ockam/src/relay_service/relay.rs index 5a5bd4a71ae..a8138841865 100644 --- a/implementations/rust/ockam/ockam/src/relay_service/relay.rs +++ b/implementations/rust/ockam/ockam/src/relay_service/relay.rs @@ -17,7 +17,7 @@ pub(super) struct Relay { } impl Relay { - pub(super) async fn create( + pub(super) fn create( ctx: &Context, address: Address, forward_route: Route, @@ -44,8 +44,7 @@ impl Relay { .with_address(address) .with_incoming_access_control_arc(incoming_access_control) .with_outgoing_access_control_arc(outgoing_access_control) - .start(ctx) - .await?; + .start(ctx)?; Ok(()) } @@ -65,7 +64,7 @@ impl Worker for Relay { ctx.forward( LocalMessage::new() .with_onward_route(self.forward_route.clone()) - .with_return_route(route![ctx.address()]) + .with_return_route(route![ctx.primary_address().clone()]) .with_payload(payload), ) .await?; @@ -85,17 +84,17 @@ impl Worker for Relay { local_message = local_message .pop_front_onward_route()? - .prepend_front_onward_route(&self.forward_route); + .prepend_front_onward_route(self.forward_route.clone()); let next_hop = local_message.next_on_onward_route()?; let prev_hop = local_message.return_route().next()?; if let Some(info) = ctx .flow_controls() - .find_flow_control_with_producer_address(&next_hop) + .find_flow_control_with_producer_address(next_hop) { ctx.flow_controls() - .add_consumer(prev_hop.clone(), info.flow_control_id()); + .add_consumer(prev_hop, info.flow_control_id()); } if let Some(info) = ctx @@ -103,7 +102,7 @@ impl Worker for Relay { .find_flow_control_with_producer_address(prev_hop) { ctx.flow_controls() - .add_consumer(next_hop.clone(), info.flow_control_id()); + .add_consumer(next_hop, info.flow_control_id()); } ctx.forward(local_message).await diff --git a/implementations/rust/ockam/ockam/src/relay_service/relay_service.rs b/implementations/rust/ockam/ockam/src/relay_service/relay_service.rs index 9a2b1049d45..a9d5c0c1640 100644 --- a/implementations/rust/ockam/ockam/src/relay_service/relay_service.rs +++ b/implementations/rust/ockam/ockam/src/relay_service/relay_service.rs @@ -20,7 +20,7 @@ pub struct RelayService { impl RelayService { /// Start a forwarding service - pub async fn create( + pub fn create( ctx: &Context, address: impl Into
, options: RelayServiceOptions, @@ -33,6 +33,7 @@ impl RelayService { options.setup_flow_control_for_relay_service(ctx.flow_controls(), alias); additional_mailboxes.push(Mailbox::new( alias.clone(), + None, options.service_incoming_access_control.clone(), Arc::new(DenyAll), )); @@ -45,13 +46,13 @@ impl RelayService { .with_mailboxes(Mailboxes::new( Mailbox::new( address.clone(), + None, service_incoming_access_control, Arc::new(DenyAll), ), additional_mailboxes, )) - .start(ctx) - .await?; + .start(ctx)?; info!("Relay service started at {address}"); @@ -141,8 +142,7 @@ impl Worker for RelayService { forward_route, payload.to_vec(), self.options.relays_incoming_access_control.clone(), - ) - .await?; + )?; Ok(()) } diff --git a/implementations/rust/ockam/ockam/src/remote/lifecycle.rs b/implementations/rust/ockam/ockam/src/remote/lifecycle.rs index ac0768553ac..e3a42d0ab2a 100644 --- a/implementations/rust/ockam/ockam/src/remote/lifecycle.rs +++ b/implementations/rust/ockam/ockam/src/remote/lifecycle.rs @@ -4,8 +4,7 @@ use ockam_core::compat::string::{String, ToString}; use ockam_core::compat::sync::Arc; use ockam_core::flow_control::FlowControlId; use ockam_core::{ - route, AllowAll, AllowSourceAddress, DenyAll, Mailbox, Mailboxes, OutgoingAccessControl, - Result, Route, + AllowAll, AllowSourceAddress, DenyAll, Mailbox, Mailboxes, OutgoingAccessControl, Result, Route, }; use ockam_node::WorkerBuilder; use tracing::debug; @@ -32,12 +31,14 @@ impl RemoteRelay { ) -> Mailboxes { let main_internal = Mailbox::new( addresses.main_internal, + None, Arc::new(DenyAll), outgoing_access_control, ); let main_remote = Mailbox::new( addresses.main_remote, + None, Arc::new(AllowAll), Arc::new(AllowAll), ); @@ -71,15 +72,13 @@ impl RemoteRelay { ) -> Result { let addresses = Addresses::generate(RelayType::Static); - let mut callback_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - addresses.completion_callback.clone(), - Arc::new(AllowSourceAddress(addresses.main_remote.clone())), - Arc::new(DenyAll), - )) - .await?; + let mut callback_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + addresses.completion_callback.clone(), + Arc::new(AllowSourceAddress(addresses.main_remote.clone())), + Arc::new(DenyAll), + ))?; - let registration_route = route![orchestrator_route.into(), "static_forwarding_service"]; + let registration_route = orchestrator_route.into() + "static_forwarding_service"; let flow_control_id = options.setup_flow_control(ctx.flow_controls(), &addresses, registration_route.next()?); @@ -97,8 +96,7 @@ impl RemoteRelay { let mailboxes = Self::mailboxes(addresses, outgoing_access_control); WorkerBuilder::new(relay) .with_mailboxes(mailboxes) - .start(ctx) - .await?; + .start(ctx)?; let resp = callback_ctx .receive::() @@ -116,15 +114,13 @@ impl RemoteRelay { ) -> Result { let addresses = Addresses::generate(RelayType::Ephemeral); - let mut callback_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - addresses.completion_callback.clone(), - Arc::new(AllowSourceAddress(addresses.main_remote.clone())), - Arc::new(DenyAll), - )) - .await?; + let mut callback_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + addresses.completion_callback.clone(), + Arc::new(AllowSourceAddress(addresses.main_remote.clone())), + Arc::new(DenyAll), + ))?; - let registration_route = route![orchestrator_route, "forwarding_service"]; + let registration_route = orchestrator_route.into() + "forwarding_service"; let flow_control_id = options.setup_flow_control(ctx.flow_controls(), &addresses, registration_route.next()?); @@ -145,8 +141,7 @@ impl RemoteRelay { let mailboxes = Self::mailboxes(addresses, outgoing_access_control); WorkerBuilder::new(relay) .with_mailboxes(mailboxes) - .start(ctx) - .await?; + .start(ctx)?; let resp = callback_ctx .receive::() diff --git a/implementations/rust/ockam/ockam/src/remote/options.rs b/implementations/rust/ockam/ockam/src/remote/options.rs index e1fdd5962cc..e62beec1da3 100644 --- a/implementations/rust/ockam/ockam/src/remote/options.rs +++ b/implementations/rust/ockam/ockam/src/remote/options.rs @@ -29,14 +29,9 @@ impl RemoteRelayOptions { .map(|x| x.flow_control_id().clone()) { // Allow a sender with corresponding flow_control_id send messages to this address - flow_controls.add_consumer(addresses.main_remote.clone(), &flow_control_id); + flow_controls.add_consumer(&addresses.main_remote, &flow_control_id); - flow_controls.add_producer( - addresses.main_internal.clone(), - &flow_control_id, - None, - vec![], - ); + flow_controls.add_producer(&addresses.main_internal, &flow_control_id, None, vec![]); Some(flow_control_id) } else { diff --git a/implementations/rust/ockam/ockam/src/remote/worker.rs b/implementations/rust/ockam/ockam/src/remote/worker.rs index 8adc0e61fc7..4f2a294d87d 100644 --- a/implementations/rust/ockam/ockam/src/remote/worker.rs +++ b/implementations/rust/ockam/ockam/src/remote/worker.rs @@ -42,7 +42,7 @@ impl Worker for RemoteRelay { Err(_) => { debug!(registration_route = %self.registration_route, "RemoteRelay received service message"); - let payload = String::decode(local_message.payload_ref()) + let payload = String::decode(local_message.payload()) .map_err(|_| OckamError::InvalidResponseFromRelayService)?; // using ends_with() instead of == to allow for prefixes if self.registration_payload != "register" diff --git a/implementations/rust/ockam/ockam/tests/async_try_clone/fail_if_attr_crate_unsupported.rs b/implementations/rust/ockam/ockam/tests/async_try_clone/fail_if_attr_crate_unsupported.rs deleted file mode 100644 index 4517c4113d2..00000000000 --- a/implementations/rust/ockam/ockam/tests/async_try_clone/fail_if_attr_crate_unsupported.rs +++ /dev/null @@ -1,9 +0,0 @@ -use ockam_core::AsyncTryClone; - -#[derive(AsyncTryClone)] -#[async_try_clone(crate = "my_crate")] -pub struct Tmp { - a: u32, -} - -fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/async_try_clone/fail_if_attr_crate_unsupported.stderr b/implementations/rust/ockam/ockam/tests/async_try_clone/fail_if_attr_crate_unsupported.stderr deleted file mode 100644 index e422a7e054b..00000000000 --- a/implementations/rust/ockam/ockam/tests/async_try_clone/fail_if_attr_crate_unsupported.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: only `ockam`, `ockam_core` or `crate` are supported, got `my_crate` - --> tests/async_try_clone/fail_if_attr_crate_unsupported.rs:4:27 - | -4 | #[async_try_clone(crate = "my_crate")] - | ^^^^^^^^^^ diff --git a/implementations/rust/ockam/ockam/tests/macro_expand_playground.rs b/implementations/rust/ockam/ockam/tests/macro_expand_playground.rs index 10239eba842..3236f6e9aa2 100644 --- a/implementations/rust/ockam/ockam/tests/macro_expand_playground.rs +++ b/implementations/rust/ockam/ockam/tests/macro_expand_playground.rs @@ -7,5 +7,5 @@ #[ockam::test(crate = "ockam", timeout = 100)] #[ignore] async fn my_test(ctx: &mut ockam::Context) -> ockam::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam/tests/main.rs b/implementations/rust/ockam/ockam/tests/main.rs index 5faaba91006..fda8725f6cc 100644 --- a/implementations/rust/ockam/ockam/tests/main.rs +++ b/implementations/rust/ockam/ockam/tests/main.rs @@ -1,11 +1,11 @@ #[test] -fn async_try_clone() { +fn try_clone() { let t = trybuild::TestCases::new(); // see the other use of `NIGHTLY_CI` for explanation. if std::env::var_os("NIGHTLY_CI").is_none() { - t.compile_fail("tests/async_try_clone/fail*.rs"); + t.compile_fail("tests/try_clone/fail*.rs"); } - t.pass("tests/async_try_clone/pass.rs"); + t.pass("tests/try_clone/pass.rs"); } #[test] diff --git a/implementations/rust/ockam/ockam/tests/node/std/fail_if_function_is_not_named_main.rs b/implementations/rust/ockam/ockam/tests/node/std/fail_if_function_is_not_named_main.rs index f9c0c8568e9..339098b097a 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/fail_if_function_is_not_named_main.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/fail_if_function_is_not_named_main.rs @@ -1,4 +1,4 @@ #[ockam::node] fn foo(c: ockam::Context) { - c.stop().await.unwrap(); + c.shutdown_node().await.unwrap(); } diff --git a/implementations/rust/ockam/ockam/tests/node/std/fail_if_macro_has_unsupported_attr.rs b/implementations/rust/ockam/ockam/tests/node/std/fail_if_macro_has_unsupported_attr.rs index 79cf846b77b..2e08767098f 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/fail_if_macro_has_unsupported_attr.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/fail_if_macro_has_unsupported_attr.rs @@ -1,4 +1,4 @@ #[ockam::node(timeout = 100)] async fn main(c: ockam::Context) { - c.stop().await.unwrap(); + c.shutdown_node().await.unwrap(); } diff --git a/implementations/rust/ockam/ockam/tests/node/std/pass_with_borrowed_mutable_context.rs b/implementations/rust/ockam/ockam/tests/node/std/pass_with_borrowed_mutable_context.rs index f104858c0ce..48503750291 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/pass_with_borrowed_mutable_context.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/pass_with_borrowed_mutable_context.rs @@ -1,4 +1,4 @@ #[ockam::node] async fn main(ctx: &ockam::Context) -> ockam_core::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam/tests/node/std/pass_with_imported_context.rs b/implementations/rust/ockam/ockam/tests/node/std/pass_with_imported_context.rs index 63fa9d823ce..c2317c6e339 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/pass_with_imported_context.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/pass_with_imported_context.rs @@ -4,5 +4,5 @@ use ockam::Context; #[ockam::node] async fn main(c: Context) -> ockam_core::Result<()> { - c.stop().await + c.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam/tests/node/std/pass_with_macro_attr_crate.rs b/implementations/rust/ockam/ockam/tests/node/std/pass_with_macro_attr_crate.rs index 34299df706c..5ae7b8156e9 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/pass_with_macro_attr_crate.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/pass_with_macro_attr_crate.rs @@ -1,4 +1,4 @@ #[ockam::node(crate = "ockam_node")] async fn main(ctx: ockam_node::Context) -> ockam_core::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam/tests/node/std/pass_with_more_than_one_arg.rs b/implementations/rust/ockam/ockam/tests/node/std/pass_with_more_than_one_arg.rs index 8a524960b46..c5f20571b98 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/pass_with_more_than_one_arg.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/pass_with_more_than_one_arg.rs @@ -1,4 +1,4 @@ #[ockam::node] async fn main(c: ockam::Context, _x: u64) -> ockam_core::Result<()> { - c.stop().await + c.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam/tests/node/std/pass_with_mutable_context.rs b/implementations/rust/ockam/ockam/tests/node/std/pass_with_mutable_context.rs index 5c05984a7a5..408453bd6fd 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/pass_with_mutable_context.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/pass_with_mutable_context.rs @@ -1,4 +1,4 @@ #[ockam::node] async fn main(ctx: ockam::Context) -> ockam_core::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam/tests/node/std/pass_with_non_async_fn.rs b/implementations/rust/ockam/ockam/tests/node/std/pass_with_non_async_fn.rs index 8eff5dec08e..0592c321481 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/pass_with_non_async_fn.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/pass_with_non_async_fn.rs @@ -1,4 +1,4 @@ #[ockam::node] fn main(ctx: ockam::Context) -> ockam_core::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam/tests/node/std/pass_with_ockam_alias.rs b/implementations/rust/ockam/ockam/tests/node/std/pass_with_ockam_alias.rs index 5573ce55f98..23f95e56161 100644 --- a/implementations/rust/ockam/ockam/tests/node/std/pass_with_ockam_alias.rs +++ b/implementations/rust/ockam/ockam/tests/node/std/pass_with_ockam_alias.rs @@ -4,5 +4,5 @@ use ockam::{self as o}; #[ockam::node] async fn main(c: o::Context) -> ockam_core::Result<()> { - c.stop().await + c.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam/tests/node_test/fail_if_function_is_not_async.rs b/implementations/rust/ockam/ockam/tests/node_test/fail_if_function_is_not_async.rs index d3e6bab1775..bcf23f02609 100644 --- a/implementations/rust/ockam/ockam/tests/node_test/fail_if_function_is_not_async.rs +++ b/implementations/rust/ockam/ockam/tests/node_test/fail_if_function_is_not_async.rs @@ -1,6 +1,6 @@ #[ockam::test] fn my_test(c: &mut ockam_node::Context) -> ockam_core::Result<()> { - c.stop().await.unwrap(); + c.shutdown_node().await.unwrap(); } fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/node_test/fail_if_invalid_macro_attr_crate.rs b/implementations/rust/ockam/ockam/tests/node_test/fail_if_invalid_macro_attr_crate.rs index 07af92e26c8..88fb15f2888 100644 --- a/implementations/rust/ockam/ockam/tests/node_test/fail_if_invalid_macro_attr_crate.rs +++ b/implementations/rust/ockam/ockam/tests/node_test/fail_if_invalid_macro_attr_crate.rs @@ -1,6 +1,6 @@ #[ockam::test(crate = 1000)] async fn my_test(ctx: &mut ockam_node::Context) -> ockam_core::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/node_test/fail_if_more_than_one_arg.rs b/implementations/rust/ockam/ockam/tests/node_test/fail_if_more_than_one_arg.rs index 8d938250b73..4fb623a4f7c 100644 --- a/implementations/rust/ockam/ockam/tests/node_test/fail_if_more_than_one_arg.rs +++ b/implementations/rust/ockam/ockam/tests/node_test/fail_if_more_than_one_arg.rs @@ -1,6 +1,6 @@ #[ockam::test] async fn my_test(mut c: ockam_node::Context, _x: u64) -> ockam_core::Result<()> { - c.stop().await.unwrap(); + c.shutdown_node().await.unwrap(); } fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/node_test/fail_with_mutable_context.rs b/implementations/rust/ockam/ockam/tests/node_test/fail_with_mutable_context.rs index 6d94be415ab..dc424c82115 100644 --- a/implementations/rust/ockam/ockam/tests/node_test/fail_with_mutable_context.rs +++ b/implementations/rust/ockam/ockam/tests/node_test/fail_with_mutable_context.rs @@ -1,6 +1,6 @@ #[ockam::test] async fn my_test(mut ctx: Context) -> ockam_core::Result<()> { - ctx.stop().await.unwrap(); + ctx.shutdown_node().await.unwrap(); } fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/node_test/fail_with_owned_context.rs b/implementations/rust/ockam/ockam/tests/node_test/fail_with_owned_context.rs index 883d68c5a95..04a3120b025 100644 --- a/implementations/rust/ockam/ockam/tests/node_test/fail_with_owned_context.rs +++ b/implementations/rust/ockam/ockam/tests/node_test/fail_with_owned_context.rs @@ -1,6 +1,6 @@ #[ockam::test] async fn my_test(ctx: Context) -> ockam_core::Result<()> { - ctx.stop().await.unwrap(); + ctx.shutdown_node().await.unwrap(); } fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_attr_crate.rs b/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_attr_crate.rs index 38e947297a7..787e16e1c85 100644 --- a/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_attr_crate.rs +++ b/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_attr_crate.rs @@ -1,6 +1,6 @@ #[ockam::test(crate = "ockam")] async fn my_test(ctx: &mut ockam::Context) -> ockam_core::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_attr_timeout.rs b/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_attr_timeout.rs index 0e14df8572f..bdad534b0a4 100644 --- a/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_attr_timeout.rs +++ b/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_attr_timeout.rs @@ -1,6 +1,6 @@ #[ockam::test(timeout = 1000)] async fn my_test(ctx: &mut ockam_node::Context) -> ockam_core::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_without_attrs.rs b/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_without_attrs.rs index 3c682d025e7..c46bf0e88f6 100644 --- a/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_without_attrs.rs +++ b/implementations/rust/ockam/ockam/tests/node_test/pass_with_macro_without_attrs.rs @@ -1,6 +1,6 @@ #[ockam::test] async fn my_test(ctx: &mut ockam_node::Context) -> ockam_core::Result<()> { - ctx.stop().await + ctx.shutdown_node().await } fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/relay.rs b/implementations/rust/ockam/ockam/tests/relay.rs index aa14edf6927..de23abede06 100644 --- a/implementations/rust/ockam/ockam/tests/relay.rs +++ b/implementations/rust/ockam/ockam/tests/relay.rs @@ -10,9 +10,9 @@ use std::time::Duration; // Node creates a Relay service and a Remote Relay, Echoer is reached through the Relay. No flow control #[ockam_macros::test] async fn test1(ctx: &mut Context) -> Result<()> { - RelayService::create(ctx, "forwarding_service", RelayServiceOptions::new()).await?; + RelayService::create(ctx, "forwarding_service", RelayServiceOptions::new())?; - ctx.start_worker("echoer", Echoer).await?; + ctx.start_worker("echoer", Echoer)?; let remote_info = RemoteRelay::create(ctx, route![], RemoteRelayOptions::new()).await?; @@ -36,8 +36,8 @@ async fn test2(ctx: &mut Context) -> Result<()> { let options = RelayServiceOptions::new() .service_as_consumer(&tcp_listener_options.spawner_flow_control_id()) .relay_as_consumer(&tcp_listener_options.spawner_flow_control_id()); - RelayService::create(ctx, "forwarding_service", options).await?; - let cloud_tcp = TcpTransport::create(ctx).await?; + RelayService::create(ctx, "forwarding_service", options)?; + let cloud_tcp = TcpTransport::create(ctx)?; let cloud_listener = cloud_tcp .listen("127.0.0.1:0", tcp_listener_options) @@ -45,11 +45,11 @@ async fn test2(ctx: &mut Context) -> Result<()> { let tcp_options = TcpConnectionOptions::new(); - ctx.start_worker("echoer", Echoer).await?; + ctx.start_worker("echoer", Echoer)?; ctx.flow_controls() - .add_consumer("echoer", &tcp_options.flow_control_id()); + .add_consumer(&"echoer".into(), &tcp_options.flow_control_id()); - let server_tcp = TcpTransport::create(ctx).await?; + let server_tcp = TcpTransport::create(ctx)?; let cloud_connection = server_tcp .connect(cloud_listener.socket_string(), tcp_options) .await?; @@ -57,7 +57,7 @@ async fn test2(ctx: &mut Context) -> Result<()> { let remote_info = RemoteRelay::create(ctx, cloud_connection.clone(), RemoteRelayOptions::new()).await?; - let client_tcp = TcpTransport::create(ctx).await?; + let client_tcp = TcpTransport::create(ctx)?; let cloud_connection = client_tcp .connect(cloud_listener.socket_string(), TcpConnectionOptions::new()) .await?; @@ -81,8 +81,8 @@ async fn test3(ctx: &mut Context) -> Result<()> { let options = RelayServiceOptions::new() .service_as_consumer(&tcp_listener_options.spawner_flow_control_id()) .relay_as_consumer(&tcp_listener_options.spawner_flow_control_id()); - RelayService::create(ctx, "forwarding_service", options).await?; - let cloud_tcp = TcpTransport::create(ctx).await?; + RelayService::create(ctx, "forwarding_service", options)?; + let cloud_tcp = TcpTransport::create(ctx)?; let cloud_listener = cloud_tcp .listen("127.0.0.1:0", tcp_listener_options) .await?; @@ -90,7 +90,7 @@ async fn test3(ctx: &mut Context) -> Result<()> { let tcp_options = TcpConnectionOptions::new(); let server_tcp_flow_control_id = tcp_options.flow_control_id(); - let server_tcp = TcpTransport::create(ctx).await?; + let server_tcp = TcpTransport::create(ctx)?; let cloud_connection = server_tcp .connect(cloud_listener.socket_string(), tcp_options) .await?; @@ -98,7 +98,7 @@ async fn test3(ctx: &mut Context) -> Result<()> { let remote_info = RemoteRelay::create(ctx, cloud_connection.clone(), RemoteRelayOptions::new()).await?; - let mut child_ctx = ctx.new_detached("ctx", AllowAll, AllowAll).await?; + let mut child_ctx = ctx.new_detached("ctx", AllowAll, AllowAll)?; ctx.send( route![remote_info.remote_address(), "ctx"], "Hello".to_string(), @@ -114,7 +114,7 @@ async fn test3(ctx: &mut Context) -> Result<()> { assert!(res.is_err(), "Should not pass outgoing access control"); ctx.flow_controls() - .add_consumer("ctx", &server_tcp_flow_control_id); + .add_consumer(&"ctx".into(), &server_tcp_flow_control_id); ctx.send( route![remote_info.remote_address(), "ctx"], @@ -159,21 +159,19 @@ async fn test4(ctx: &mut Context) -> Result<()> { let options = RelayServiceOptions::new() .service_as_consumer(&cloud_secure_channel_listener_options.spawner_flow_control_id()) .relay_as_consumer(&cloud_secure_channel_listener_options.spawner_flow_control_id()); - RelayService::create(ctx, "forwarding_service", options).await?; + RelayService::create(ctx, "forwarding_service", options)?; let secure_channels = secure_channels().await?; let identities_creation = secure_channels.identities().identities_creation(); let cloud = identities_creation.create_identity().await?; - secure_channels - .create_secure_channel_listener( - ctx, - &cloud, - "cloud_listener", - cloud_secure_channel_listener_options, - ) - .await?; - - let cloud_tcp = TcpTransport::create(ctx).await?; + secure_channels.create_secure_channel_listener( + ctx, + &cloud, + "cloud_listener", + cloud_secure_channel_listener_options, + )?; + + let cloud_tcp = TcpTransport::create(ctx)?; let cloud_listener = cloud_tcp .listen("127.0.0.1:0", cloud_tcp_listener_options) .await?; @@ -183,13 +181,13 @@ async fn test4(ctx: &mut Context) -> Result<()> { let server_secure_channel_listener_options = SecureChannelListenerOptions::new() .as_consumer(&server_secure_channel_options.producer_flow_control_id()); - ctx.start_worker("echoer", Echoer).await?; + ctx.start_worker("echoer", Echoer)?; ctx.flow_controls().add_consumer( - "echoer", + &"echoer".into(), &server_secure_channel_listener_options.spawner_flow_control_id(), ); - let server_tcp = TcpTransport::create(ctx).await?; + let server_tcp = TcpTransport::create(ctx)?; let cloud_server_connection = server_tcp .connect(cloud_listener.socket_string(), TcpConnectionOptions::new()) .await?; @@ -202,20 +200,18 @@ async fn test4(ctx: &mut Context) -> Result<()> { server_secure_channel_options, ) .await?; - secure_channels - .create_secure_channel_listener( - ctx, - &server, - "server_listener", - server_secure_channel_listener_options, - ) - .await?; + secure_channels.create_secure_channel_listener( + ctx, + &server, + "server_listener", + server_secure_channel_listener_options, + )?; let remote_info = RemoteRelay::create(ctx, cloud_server_channel.clone(), RemoteRelayOptions::new()).await?; // Client - let client_tcp = TcpTransport::create(ctx).await?; + let client_tcp = TcpTransport::create(ctx)?; let cloud_client_connection = client_tcp .connect(cloud_listener.socket_string(), TcpConnectionOptions::new()) .await?; diff --git a/implementations/rust/ockam/ockam/tests/try_clone/fail_if_attr_crate_unsupported.rs b/implementations/rust/ockam/ockam/tests/try_clone/fail_if_attr_crate_unsupported.rs new file mode 100644 index 00000000000..eb666d94f64 --- /dev/null +++ b/implementations/rust/ockam/ockam/tests/try_clone/fail_if_attr_crate_unsupported.rs @@ -0,0 +1,9 @@ +use ockam_core::TryClone; + +#[derive(TryClone)] +#[try_clone(crate = "my_crate")] +pub struct Tmp { + a: u32, +} + +fn main() {} diff --git a/implementations/rust/ockam/ockam/tests/try_clone/fail_if_attr_crate_unsupported.stderr b/implementations/rust/ockam/ockam/tests/try_clone/fail_if_attr_crate_unsupported.stderr new file mode 100644 index 00000000000..695fdbfd04d --- /dev/null +++ b/implementations/rust/ockam/ockam/tests/try_clone/fail_if_attr_crate_unsupported.stderr @@ -0,0 +1,5 @@ +error: only `ockam`, `ockam_core` or `crate` are supported, got `my_crate` + --> tests/try_clone/fail_if_attr_crate_unsupported.rs:4:21 + | +4 | #[try_clone(crate = "my_crate")] + | ^^^^^^^^^^ diff --git a/implementations/rust/ockam/ockam/tests/async_try_clone/pass.rs b/implementations/rust/ockam/ockam/tests/try_clone/pass.rs similarity index 58% rename from implementations/rust/ockam/ockam/tests/async_try_clone/pass.rs rename to implementations/rust/ockam/ockam/tests/try_clone/pass.rs index c016230fc73..da60367b06b 100644 --- a/implementations/rust/ockam/ockam/tests/async_try_clone/pass.rs +++ b/implementations/rust/ockam/ockam/tests/try_clone/pass.rs @@ -1,25 +1,25 @@ -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; -#[derive(AsyncTryClone)] +#[derive(TryClone)] pub struct Tmp { a: u32, } -#[derive(AsyncTryClone)] -#[async_try_clone(crate = "ockam")] +#[derive(TryClone)] +#[try_clone(crate = "ockam")] pub struct Tmp1 { a: u32, b: Vec, } -#[derive(AsyncTryClone)] -#[async_try_clone(crate = "ockam_core")] +#[derive(TryClone)] +#[try_clone(crate = "ockam_core")] pub struct Tmp2 { a: u32, b: T, } -fn assert_impl() {} +fn assert_impl() {} fn main() { assert_impl::(); assert_impl::(); diff --git a/implementations/rust/ockam/ockam_abac/src/abac/abac.rs b/implementations/rust/ockam/ockam_abac/src/abac/abac.rs index 0a9b7aa6976..4a129c1c854 100644 --- a/implementations/rust/ockam/ockam_abac/src/abac/abac.rs +++ b/implementations/rust/ockam/ockam_abac/src/abac/abac.rs @@ -59,20 +59,19 @@ impl Abac { } impl Abac { - pub async fn get_outgoing_identifier( + pub fn get_outgoing_identifier( ctx: &Context, relay_msg: &RelayMessage, ) -> Result> { - let terminal = if let Some(terminal) = ctx - .find_terminal_address(relay_msg.onward_route().clone()) - .await? + let metadata = if let Some((_address, metadata)) = + ctx.find_terminal_address(relay_msg.onward_route().iter())? { - terminal + metadata } else { return Ok(None); }; - if let Ok(metadata) = SecureChannelMetadata::from_terminal_address(&terminal) { + if let Ok(metadata) = SecureChannelMetadata::from_terminal_address_metadata(&metadata) { Ok(Some(metadata.their_identifier().into())) } else { Ok(None) diff --git a/implementations/rust/ockam/ockam_abac/src/abac/outgoing.rs b/implementations/rust/ockam/ockam_abac/src/abac/outgoing.rs index dabc04632c6..b0affcf36ba 100644 --- a/implementations/rust/ockam/ockam_abac/src/abac/outgoing.rs +++ b/implementations/rust/ockam/ockam_abac/src/abac/outgoing.rs @@ -35,15 +35,13 @@ impl Debug for OutgoingAbac { impl OutgoingAbac { /// Create an AccessControl which will verify that the receiver of /// a message has an authenticated attribute that resolves the expression to `true` - pub async fn create( + pub fn create( ctx: &Context, identities_attributes: Arc, authority: Option, expression: Expr, ) -> Result { - let ctx = ctx - .new_detached(Address::random_tagged("OutgoingAbac"), DenyAll, DenyAll) - .await?; + let ctx = ctx.new_detached(Address::random_tagged("OutgoingAbac"), DenyAll, DenyAll)?; let abac = Abac::new(identities_attributes, authority, Env::new()); Ok(Self { @@ -55,7 +53,7 @@ impl OutgoingAbac { /// Create an AccessControl which will verify that the receiver of /// a message has an authenticated attribute with the correct name and value - pub async fn create_name_value( + pub fn create_name_value( ctx: &Context, identities_attributes: Arc, authority: Option, @@ -67,22 +65,22 @@ impl OutgoingAbac { Ident(format!("{SUBJECT_KEY}.{attribute_name}")), Str(attribute_value.into()), ]); - Self::create(ctx, identities_attributes, authority, expression).await + Self::create(ctx, identities_attributes, authority, expression) } /// Create an AccessControl which will verify that the receiver of /// a message has an authenticated credential without checking any attributes - pub async fn check_credential_only( + pub fn check_credential_only( ctx: &Context, identities_attributes: Arc, authority: Identifier, ) -> Result { - Self::create(ctx, identities_attributes, Some(authority), true.into()).await + Self::create(ctx, identities_attributes, Some(authority), true.into()) } /// Returns true if the sender of the message is validated by the expression stored in AbacAccessControl pub async fn is_authorized_impl(&self, relay_msg: &RelayMessage) -> Result { - let identifier = match Abac::get_outgoing_identifier(&self.ctx, relay_msg).await? { + let identifier = match Abac::get_outgoing_identifier(&self.ctx, relay_msg)? { Some(identifier) => identifier, None => { debug! { diff --git a/implementations/rust/ockam/ockam_abac/src/policy/access_control.rs b/implementations/rust/ockam/ockam_abac/src/policy/access_control.rs index 81ed4213e22..dd8bb7b4c7d 100644 --- a/implementations/rust/ockam/ockam_abac/src/policy/access_control.rs +++ b/implementations/rust/ockam/ockam_abac/src/policy/access_control.rs @@ -62,14 +62,12 @@ impl PolicyAccessControl { } } - pub async fn create_outgoing(&self, ctx: &Context) -> Result { - let ctx = ctx - .new_detached( - Address::random_tagged("OutgoingPolicyAbac"), - DenyAll, - DenyAll, - ) - .await?; + pub fn create_outgoing(&self, ctx: &Context) -> Result { + let ctx = ctx.new_detached( + Address::random_tagged("OutgoingPolicyAbac"), + DenyAll, + DenyAll, + )?; Ok(OutgoingPolicyAccessControl { ctx, diff --git a/implementations/rust/ockam/ockam_abac/src/policy/outgoing.rs b/implementations/rust/ockam/ockam_abac/src/policy/outgoing.rs index 7c7f97defc4..2311a3a3eae 100644 --- a/implementations/rust/ockam/ockam_abac/src/policy/outgoing.rs +++ b/implementations/rust/ockam/ockam_abac/src/policy/outgoing.rs @@ -45,7 +45,7 @@ impl OutgoingAccessControl for OutgoingPolicyAccessControl { return Ok(false); }; - let identifier = match Abac::get_outgoing_identifier(&self.ctx, relay_msg).await? { + let identifier = match Abac::get_outgoing_identifier(&self.ctx, relay_msg)? { Some(identifier) => identifier, None => { debug! { diff --git a/implementations/rust/ockam/ockam_api/src/authority_node/authority.rs b/implementations/rust/ockam/ockam_api/src/authority_node/authority.rs index fe660ebf83d..cee31fc8011 100644 --- a/implementations/rust/ockam/ockam_api/src/authority_node/authority.rs +++ b/implementations/rust/ockam/ockam_api/src/authority_node/authority.rs @@ -134,13 +134,16 @@ impl Authority { let secure_channel_listener_flow_control_id = options.spawner_flow_control_id().clone(); let listener_name = configuration.secure_channel_listener_name(); - self.secure_channels - .create_secure_channel_listener(ctx, &self.identifier(), listener_name.clone(), options) - .await?; + self.secure_channels.create_secure_channel_listener( + ctx, + &self.identifier(), + listener_name.clone(), + options, + )?; info!("started a secure channel listener with name '{listener_name}'"); // Create a TCP listener and wait for incoming connections - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let listener = tcp .listen( @@ -154,7 +157,7 @@ impl Authority { } /// Start the authenticator service to enroll project members - pub async fn start_direct_authenticator( + pub fn start_direct_authenticator( &self, ctx: &Context, secure_channel_flow_control_id: &FlowControlId, @@ -172,16 +175,16 @@ impl Authority { let name = configuration.authenticator_name(); ctx.flow_controls() - .add_consumer(name.clone(), secure_channel_flow_control_id); + .add_consumer(&name.clone().into(), secure_channel_flow_control_id); - ctx.start_worker(name.clone(), direct).await?; + ctx.start_worker(name.clone(), direct)?; info!("started a direct authenticator at '{name}'"); Ok(()) } /// Start the enrollment services, to issue and accept tokens - pub async fn start_enrollment_services( + pub fn start_enrollment_services( &self, ctx: &Context, secure_channel_flow_control_id: &FlowControlId, @@ -203,20 +206,24 @@ impl Authority { // start an enrollment token issuer with an abac policy checking that // the caller is an enroller for the authority project let issuer_address: String = DefaultAddress::ENROLLMENT_TOKEN_ISSUER.into(); - ctx.flow_controls() - .add_consumer(issuer_address.clone(), secure_channel_flow_control_id); + ctx.flow_controls().add_consumer( + &issuer_address.clone().into(), + secure_channel_flow_control_id, + ); - ctx.start_worker(issuer_address.clone(), issuer).await?; + ctx.start_worker(issuer_address.clone(), issuer)?; // start an enrollment token acceptor allowing any incoming message as long as // it comes through a secure channel. We accept any message since the purpose of // that service is to access a one-time token stating that the sender of the message // is a project member let acceptor_address: String = DefaultAddress::ENROLLMENT_TOKEN_ACCEPTOR.into(); - ctx.flow_controls() - .add_consumer(acceptor_address.clone(), secure_channel_flow_control_id); + ctx.flow_controls().add_consumer( + &acceptor_address.clone().into(), + secure_channel_flow_control_id, + ); - ctx.start_worker(acceptor_address.clone(), acceptor).await?; + ctx.start_worker(acceptor_address.clone(), acceptor)?; info!("started an enrollment token issuer at '{issuer_address}'"); info!("started an enrollment token acceptor at '{acceptor_address}'"); @@ -225,7 +232,7 @@ impl Authority { /// Start the credential issuer service to issue credentials for a identities /// known to the authority - pub async fn start_credential_issuer( + pub fn start_credential_issuer( &self, ctx: &Context, secure_channel_flow_control_id: &FlowControlId, @@ -247,16 +254,16 @@ impl Authority { let address = DefaultAddress::CREDENTIAL_ISSUER.to_string(); ctx.flow_controls() - .add_consumer(address.clone(), secure_channel_flow_control_id); + .add_consumer(&address.clone().into(), secure_channel_flow_control_id); - ctx.start_worker(address.clone(), issuer).await?; + ctx.start_worker(address.clone(), issuer)?; info!("started a credential issuer at '{address}'"); Ok(()) } /// Start the Okta service to retrieve attributes authenticated by Okta - pub async fn start_okta( + pub fn start_okta( &self, ctx: &Context, secure_channel_flow_control_id: &FlowControlId, @@ -271,15 +278,15 @@ impl Authority { )?; ctx.flow_controls() - .add_consumer(okta.address.clone(), secure_channel_flow_control_id); + .add_consumer(&okta.address.clone().into(), secure_channel_flow_control_id); - ctx.start_worker(okta.address.clone(), okta_worker).await?; + ctx.start_worker(okta.address.clone(), okta_worker)?; } Ok(()) } /// Start an echo service - pub async fn start_echo_service( + pub fn start_echo_service( &self, ctx: &Context, secure_channel_flow_control_id: &FlowControlId, @@ -287,9 +294,9 @@ impl Authority { let address = DefaultAddress::ECHO_SERVICE; ctx.flow_controls() - .add_consumer(address, secure_channel_flow_control_id); + .add_consumer(&address.into(), secure_channel_flow_control_id); - ctx.start_worker(address, Echoer).await + ctx.start_worker(address, Echoer) } /// Add a member directly to storage, without additional validation diff --git a/implementations/rust/ockam/ockam_api/src/authority_node/node.rs b/implementations/rust/ockam/ockam_api/src/authority_node/node.rs index 06013a882a2..5f6ff27438d 100644 --- a/implementations/rust/ockam/ockam_api/src/authority_node/node.rs +++ b/implementations/rust/ockam/ockam_api/src/authority_node/node.rs @@ -19,31 +19,21 @@ pub async fn start_node( debug!("secure channel listener started"); // start the authenticator services - authority - .start_direct_authenticator(ctx, &secure_channel_flow_control_id, configuration) - .await?; + authority.start_direct_authenticator(ctx, &secure_channel_flow_control_id, configuration)?; debug!("direct authenticator started"); - authority - .start_enrollment_services(ctx, &secure_channel_flow_control_id, configuration) - .await?; + authority.start_enrollment_services(ctx, &secure_channel_flow_control_id, configuration)?; debug!("enrollment services started"); - authority - .start_credential_issuer(ctx, &secure_channel_flow_control_id, configuration) - .await?; + authority.start_credential_issuer(ctx, &secure_channel_flow_control_id, configuration)?; debug!("credential issuer started"); // start the Okta service (if the optional configuration has been provided) - authority - .start_okta(ctx, &secure_channel_flow_control_id, configuration) - .await?; + authority.start_okta(ctx, &secure_channel_flow_control_id, configuration)?; debug!("okta service started"); // start an echo service so that the node can be queried as healthy - authority - .start_echo_service(ctx, &secure_channel_flow_control_id) - .await?; + authority.start_echo_service(ctx, &secure_channel_flow_control_id)?; debug!("echo service started"); diff --git a/implementations/rust/ockam/ockam_api/src/hop.rs b/implementations/rust/ockam/ockam_api/src/hop.rs index b07a067427c..3c6d7f7d089 100644 --- a/implementations/rust/ockam/ockam_api/src/hop.rs +++ b/implementations/rust/ockam/ockam_api/src/hop.rs @@ -12,7 +12,10 @@ impl Worker for Hop { /// it to the next hop in it's onward route async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { // Send the message on its onward_route - ctx.forward(msg.into_local_message().step_forward(&ctx.address())?) - .await + ctx.forward( + msg.into_local_message() + .step_forward(ctx.primary_address().clone())?, + ) + .await } } diff --git a/implementations/rust/ockam/ockam_api/src/influxdb/gateway/token_lease_refresher.rs b/implementations/rust/ockam/ockam_api/src/influxdb/gateway/token_lease_refresher.rs index 92c54dbfe8b..2d94c917f9f 100644 --- a/implementations/rust/ockam/ockam_api/src/influxdb/gateway/token_lease_refresher.rs +++ b/implementations/rust/ockam/ockam_api/src/influxdb/gateway/token_lease_refresher.rs @@ -19,18 +19,18 @@ impl TokenLeaseRefresher { let token = Arc::new(RwLock::new(Some(token))); Self { token } } - pub async fn new( + pub fn new( ctx: &Context, node_manager: Weak, lease_issuer_route: MultiAddr, ) -> Result { let token = Arc::new(RwLock::new(None)); - let mailboxes = Mailboxes::main( + let mailboxes = Mailboxes::primary( Address::random_tagged("LeaseRetriever"), Arc::new(DenyAll), Arc::new(AllowAll), ); - let new_ctx = ctx.new_detached_with_mailboxes(mailboxes).await?; + let new_ctx = ctx.new_detached_with_mailboxes(mailboxes)?; let token_clone = token.clone(); ockam_node::spawn(async move { diff --git a/implementations/rust/ockam/ockam_api/src/influxdb/lease_issuer/node_service.rs b/implementations/rust/ockam/ockam_api/src/influxdb/lease_issuer/node_service.rs index 71ff1b0c9e3..eda56daaf7d 100644 --- a/implementations/rust/ockam/ockam_api/src/influxdb/lease_issuer/node_service.rs +++ b/implementations/rust/ockam/ockam_api/src/influxdb/lease_issuer/node_service.rs @@ -38,7 +38,7 @@ impl NodeManagerWorker { } } - pub(crate) async fn delete_influxdb_lease_issuer_service( + pub(crate) fn delete_influxdb_lease_issuer_service( &self, context: &Context, req: DeleteServiceRequest, @@ -46,8 +46,7 @@ impl NodeManagerWorker { let address = req.address(); match self .node_manager - .delete_influxdb_lease_issuer_service(context, address.clone()) - .await + .delete_influxdb_lease_issuer_service(context, &address) { Ok(Some(_)) => Ok(Response::ok()), Ok(None) => Err(Response::not_found_no_request(&format!( @@ -73,10 +72,9 @@ impl InMemoryNode { .ok_or_else(|| { ApiError::core("Unable to get flow control for secure channel listener") })?; - context.flow_controls().add_consumer( - address.clone(), - &default_secure_channel_listener_flow_control_id, - ); + context + .flow_controls() + .add_consumer(&address, &default_secure_channel_listener_flow_control_id); let (incoming_ac, outgoing_ac) = self .access_control( @@ -95,43 +93,35 @@ impl InMemoryNode { req.influxdb_token, req.lease_permissions, req.expires_in, - ) - .await?; + )?; let processor = InfluxDBTokenLessorProcessor::new(worker.state.clone()); WorkerBuilder::new(worker) .with_address(address.clone()) .with_incoming_access_control_arc(incoming_ac) .with_outgoing_access_control_arc(outgoing_ac) - .start(context) - .await?; - self.registry - .influxdb_services - .insert(address.clone(), ()) - .await; + .start(context)?; + self.registry.influxdb_services.insert(address.clone(), ()); ProcessorBuilder::new(processor) .with_address(format!("{address}-processor")) - .start(context) - .await?; + .start(context)?; Ok(()) } - async fn delete_influxdb_lease_issuer_service( + fn delete_influxdb_lease_issuer_service( &self, context: &Context, - address: Address, + address: &Address, ) -> Result, Error> { debug!(address = %address,"Deleting influxdb lease issuer service"); - match self.registry.influxdb_services.get(&address).await { + match self.registry.influxdb_services.get(address) { None => Ok(None), Some(_) => { - context.stop_worker(address.clone()).await?; - context - .stop_processor(format!("{address}-processor")) - .await?; - self.registry.influxdb_services.remove(&address).await; + context.stop_address(address)?; + context.stop_address(&format!("{address}-processor").into())?; + self.registry.influxdb_services.remove(address); Ok(Some(())) } } diff --git a/implementations/rust/ockam/ockam_api/src/influxdb/lease_issuer/worker.rs b/implementations/rust/ockam/ockam_api/src/influxdb/lease_issuer/worker.rs index 708c051a727..6c870c88d16 100644 --- a/implementations/rust/ockam/ockam_api/src/influxdb/lease_issuer/worker.rs +++ b/implementations/rust/ockam/ockam_api/src/influxdb/lease_issuer/worker.rs @@ -25,7 +25,7 @@ pub(crate) struct InfluxDBTokenLessorWorker { } impl InfluxDBTokenLessorWorker { - pub(crate) async fn new( + pub(crate) fn new( address: Address, influxdb_address: String, influxdb_org_id: String, diff --git a/implementations/rust/ockam/ockam_api/src/influxdb/portal.rs b/implementations/rust/ockam/ockam_api/src/influxdb/portal.rs index 7308ed4ebe2..0dd195a5b15 100644 --- a/implementations/rust/ockam/ockam_api/src/influxdb/portal.rs +++ b/implementations/rust/ockam/ockam_api/src/influxdb/portal.rs @@ -42,8 +42,7 @@ impl NodeManagerWorker { .node_manager .registry .outlets - .generate_worker_addr(worker_addr) - .await; + .generate_worker_addr(worker_addr); let outlet_address = match body.influxdb_config { InfluxDBOutletConfig::OutletWithFixedToken(token) => { let outlet_addr: Address = format!("{}_outlet", address.address()).into(); @@ -232,24 +231,23 @@ impl NodeManagerWorker { interceptor_address.clone(), Some(spawner_flow_control_id.clone()), http_interceptor_factory, - Arc::new(policy_access_control.create_outgoing(ctx).await?), + Arc::new(policy_access_control.create_outgoing(ctx)?), Arc::new(policy_access_control.create_incoming()), - ) - .await?; + )?; // every secure channel can reach this service let flow_controls = ctx.flow_controls(); flow_controls.add_consumer( - interceptor_address.clone(), + &interceptor_address, &default_secure_channel_listener_flow_control_id, ); // this spawner flow control id is used to control communication with dynamically created // outlets - flow_controls.add_spawner(interceptor_address, &spawner_flow_control_id); + flow_controls.add_spawner(&interceptor_address, &spawner_flow_control_id); // allow communication with the tcp outlet - flow_controls.add_consumer(outlet_address, &spawner_flow_control_id); + flow_controls.add_consumer(&outlet_address, &spawner_flow_control_id); Ok(()) } @@ -272,8 +270,7 @@ impl NodeManagerWorker { .await?; let token_refresher = - TokenLeaseRefresher::new(ctx, Arc::downgrade(&self.node_manager), lease_issuer_route) - .await?; + TokenLeaseRefresher::new(ctx, Arc::downgrade(&self.node_manager), lease_issuer_route)?; let http_interceptor_factory = Arc::new(HttpAuthInterceptorFactory::new(token_refresher)); PortalInletInterceptor::create( @@ -281,9 +278,8 @@ impl NodeManagerWorker { interceptor_address.clone(), http_interceptor_factory, Arc::new(policy_access_control.create_incoming()), - Arc::new(policy_access_control.create_outgoing(ctx).await?), - ) - .await?; + Arc::new(policy_access_control.create_outgoing(ctx)?), + )?; Ok(interceptor_address) } } diff --git a/implementations/rust/ockam/ockam_api/src/kafka/inlet_controller.rs b/implementations/rust/ockam/ockam_api/src/kafka/inlet_controller.rs index e13b7a5e803..7b6d6f8d568 100644 --- a/implementations/rust/ockam/ockam_api/src/kafka/inlet_controller.rs +++ b/implementations/rust/ockam/ockam_api/src/kafka/inlet_controller.rs @@ -7,7 +7,7 @@ use ockam_core::compat::collections::HashMap; use ockam_core::compat::rand::random_string; use ockam_core::compat::sync::Arc; use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{route, Error}; +use ockam_core::Error; use ockam_core::{Result, Route}; use ockam_multiaddr::MultiAddr; use ockam_node::Context; @@ -129,10 +129,7 @@ impl KafkaInletController { context, inlet_bind_address.clone(), inner.local_interceptor_route.clone(), - route![ - inner.remote_interceptor_route.clone(), - kafka_outlet_address(broker_id) - ], + inner.remote_interceptor_route.clone() + kafka_outlet_address(broker_id), inner.outlet_node_multiaddr.clone(), format!("kafka-inlet-{}", random_string()), self.policy_expression.clone(), diff --git a/implementations/rust/ockam/ockam_api/src/kafka/key_exchange/secure_channels.rs b/implementations/rust/ockam/ockam_api/src/kafka/key_exchange/secure_channels.rs index a8317e06330..33dadda86b2 100644 --- a/implementations/rust/ockam/ockam_api/src/kafka/key_exchange/secure_channels.rs +++ b/implementations/rust/ockam/ockam_api/src/kafka/key_exchange/secure_channels.rs @@ -129,8 +129,7 @@ impl KafkaKeyExchangeControllerImpl { if let Err(error) = Self::validate_consumer_credentials(&inner, &entry).await { inner .node_manager - .delete_secure_channel(context, &producer_encryptor_address) - .await?; + .delete_secure_channel(context, &producer_encryptor_address)?; return Err(error); }; @@ -142,8 +141,7 @@ impl KafkaKeyExchangeControllerImpl { { inner .node_manager - .delete_secure_channel(context, &producer_encryptor_address) - .await?; + .delete_secure_channel(context, &producer_encryptor_address)?; return Err(err); } } diff --git a/implementations/rust/ockam/ockam_api/src/kafka/protocol_aware/outlet/response.rs b/implementations/rust/ockam/ockam_api/src/kafka/protocol_aware/outlet/response.rs index 27b4661b422..673e440ed2c 100644 --- a/implementations/rust/ockam/ockam_api/src/kafka/protocol_aware/outlet/response.rs +++ b/implementations/rust/ockam/ockam_api/src/kafka/protocol_aware/outlet/response.rs @@ -68,7 +68,7 @@ impl KafkaMessageResponseInterceptor for OutletInterceptorImpl { // allow the interceptor to reach the outlet context .flow_controls() - .add_consumer(outlet_address, &self.flow_control_id); + .add_consumer(&outlet_address, &self.flow_control_id); } } } else { diff --git a/implementations/rust/ockam/ockam_api/src/kafka/tests/integration_test.rs b/implementations/rust/ockam/ockam_api/src/kafka/tests/integration_test.rs index 016fc7f062d..f6bd131fa97 100644 --- a/implementations/rust/ockam/ockam_api/src/kafka/tests/integration_test.rs +++ b/implementations/rust/ockam/ockam_api/src/kafka/tests/integration_test.rs @@ -119,8 +119,7 @@ async fn create_kafka_service( )), Arc::new(AllowAll), Arc::new(AllowAll), - ) - .await?; + )?; Ok(inlet.socket_address().port()) } @@ -154,14 +153,11 @@ async fn producer__flow_with_mock_kafka__content_encryption_and_decryption( // 1 of 'my-topic' { let mut consumer_mock_kafka = TcpServerSimulator::start("127.0.0.1:0").await; - handle - .tcp - .create_outlet( - "kafka_consumer_outlet", - HostnamePort::new("127.0.0.1", consumer_mock_kafka.port), - TcpOutletOptions::new(), - ) - .await?; + handle.tcp.create_outlet( + "kafka_consumer_outlet", + HostnamePort::new("127.0.0.1", consumer_mock_kafka.port), + TcpOutletOptions::new(), + )?; simulate_first_kafka_consumer_empty_reply_and_ignore_result( consumer_bootstrap_port, @@ -170,18 +166,15 @@ async fn producer__flow_with_mock_kafka__content_encryption_and_decryption( .await; drop(consumer_mock_kafka); // drop the outlet and re-create it when we need it later - context.stop_worker("kafka_consumer_outlet").await?; + context.stop_address(&"kafka_consumer_outlet".into())?; } let mut producer_mock_kafka = TcpServerSimulator::start("127.0.0.1:0").await; - handle - .tcp - .create_outlet( - "kafka_producer_outlet", - HostnamePort::new("127.0.0.1", producer_mock_kafka.port), - TcpOutletOptions::new(), - ) - .await?; + handle.tcp.create_outlet( + "kafka_producer_outlet", + HostnamePort::new("127.0.0.1", producer_mock_kafka.port), + TcpOutletOptions::new(), + )?; let request = simulate_kafka_producer_and_read_request(producer_bootstrap_port, &mut producer_mock_kafka) .await; @@ -211,14 +204,11 @@ async fn producer__flow_with_mock_kafka__content_encryption_and_decryption( ); let mut consumer_mock_kafka = TcpServerSimulator::start("127.0.0.1:0").await; - handle - .tcp - .create_outlet( - "kafka_consumer_outlet", - HostnamePort::new("127.0.0.1", consumer_mock_kafka.port), - TcpOutletOptions::new(), - ) - .await?; + handle.tcp.create_outlet( + "kafka_consumer_outlet", + HostnamePort::new("127.0.0.1", consumer_mock_kafka.port), + TcpOutletOptions::new(), + )?; // give the secure channel between producer and consumer to finish initialization tokio::time::sleep(Duration::from_secs(2)).await; diff --git a/implementations/rust/ockam/ockam_api/src/kafka/tests/interceptor_test.rs b/implementations/rust/ockam/ockam_api/src/kafka/tests/interceptor_test.rs index bea6e701729..5c379e33fa0 100644 --- a/implementations/rust/ockam/ockam_api/src/kafka/tests/interceptor_test.rs +++ b/implementations/rust/ockam/ockam_api/src/kafka/tests/interceptor_test.rs @@ -82,13 +82,16 @@ async fn kafka_portal_worker__pieces_of_kafka_message__message_assembled( // send 2 distinct pieces and see if the kafka message is re-assembled back context .send( - route![portal_inlet_address.clone(), context.address()], + route![ + portal_inlet_address.clone(), + context.primary_address().clone() + ], PortalMessage::Payload(first_piece_of_payload, None).to_neutral_message()?, ) .await?; context .send( - route![portal_inlet_address, context.address()], + route![portal_inlet_address, context.primary_address().clone()], PortalMessage::Payload(second_piece_of_payload, None).to_neutral_message()?, ) .await?; @@ -127,7 +130,10 @@ async fn kafka_portal_worker__double_kafka_message__message_assembled( let double_payload = request_buffer.as_ref(); context .send( - route![portal_inlet_address.clone(), context.address()], + route![ + portal_inlet_address.clone(), + context.primary_address().clone() + ], PortalMessage::Payload(double_payload, None).to_neutral_message()?, ) .await?; @@ -172,7 +178,10 @@ async fn kafka_portal_worker__bigger_than_limit_kafka_message__error( for chunk in huge_payload.chunks(MAX_PAYLOAD_SIZE) { let _error = context .send( - route![portal_inlet_address.clone(), context.address()], + route![ + portal_inlet_address.clone(), + context.primary_address().clone() + ], PortalMessage::Payload(chunk, None).to_neutral_message()?, ) .await; @@ -219,12 +228,10 @@ async fn kafka_portal_worker__almost_over_limit_than_limit_kafka_message__two_ka buffer: Default::default(), }; - context - .start_worker( - Address::from_string("tcp_payload_receiver"), - receiver.clone(), - ) - .await?; + context.start_worker( + Address::from_string("tcp_payload_receiver"), + receiver.clone(), + )?; // let's duplicate the message huge_outgoing_request.extend(huge_outgoing_request.clone()); @@ -314,7 +321,7 @@ async fn setup_only_worker(context: &mut Context, handle: &NodeManagerHandle) -> PortalInterceptorWorker::create_inlet_interceptor( context, None, - route![context.address()], + route![context.primary_address().clone()], Arc::new(AllowAll), Arc::new(AllowAll), Arc::new(KafkaMessageInterceptorWrapper::new( @@ -328,7 +335,6 @@ async fn setup_only_worker(context: &mut Context, handle: &NodeManagerHandle) -> TEST_MAX_KAFKA_MESSAGE_SIZE, )), ) - .await .unwrap() } @@ -412,7 +418,7 @@ async fn kafka_portal_worker__metadata_exchange__response_changed( let portal_inlet_address = PortalInterceptorWorker::create_inlet_interceptor( context, None, - route![context.address()], + route![context.primary_address().clone()], Arc::new(AllowAll), Arc::new(AllowAll), Arc::new(KafkaMessageInterceptorWrapper::new( @@ -425,8 +431,7 @@ async fn kafka_portal_worker__metadata_exchange__response_changed( )), MAX_KAFKA_MESSAGE_SIZE, )), - ) - .await?; + )?; let mut request_buffer = BytesMut::new(); // let's create a real kafka request and pass it through the portal @@ -438,7 +443,7 @@ async fn kafka_portal_worker__metadata_exchange__response_changed( context .send( - route![portal_inlet_address, context.address()], + route![portal_inlet_address, context.primary_address().clone()], PortalMessage::Payload(&request_buffer, None).to_neutral_message()?, ) .await?; diff --git a/implementations/rust/ockam/ockam_api/src/nodes/connection/mod.rs b/implementations/rust/ockam/ockam_api/src/nodes/connection/mod.rs index 4b118410436..43d6c42da3d 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/connection/mod.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/connection/mod.rs @@ -46,7 +46,7 @@ impl Connection { if let Some(flow_control_id) = &self.flow_control_id { context .flow_controls() - .add_consumer(address.clone(), flow_control_id); + .add_consumer(address, flow_control_id); } } @@ -70,9 +70,9 @@ impl Connection { }) } - pub async fn close(&self, context: &Context, node_manager: &NodeManager) -> Result<()> { + pub fn close(&self, context: &Context, node_manager: &NodeManager) -> Result<()> { for encryptor in &self.secure_channel_encryptors { - if let Err(error) = node_manager.delete_secure_channel(context, encryptor).await { + if let Err(error) = node_manager.delete_secure_channel(context, encryptor) { match error.code().kind { Kind::NotFound => { debug!("cannot find and delete secure channel `{encryptor}`: {error}"); @@ -91,7 +91,7 @@ impl Connection { if let Some(tcp_connection) = self.tcp_connection.as_ref() { let address = tcp_connection.sender_address().clone(); - if let Err(error) = node_manager.tcp_transport.disconnect(address.clone()).await { + if let Err(error) = node_manager.tcp_transport.disconnect(&address) { match error.code().kind { Kind::NotFound => { debug!("cannot find and disconnect tcp worker `{tcp_connection}`"); @@ -306,7 +306,7 @@ impl ConnectionBuilder { // last piece only if it's a terminal (a service connecting to another node) if last_pass && is_last { let is_terminal = ctx - .get_metadata(address.clone()) + .get_metadata(&address)? .map(|m| m.is_terminal) .unwrap_or(false); diff --git a/implementations/rust/ockam/ockam_api/src/nodes/connection/secure.rs b/implementations/rust/ockam/ockam_api/src/nodes/connection/secure.rs index 7903c177764..6c55a7ca7af 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/connection/secure.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/connection/secure.rs @@ -6,7 +6,7 @@ use crate::{local_multiaddr_to_route, try_address_to_multiaddr}; use crate::nodes::service::SecureChannelType; use ockam::identity::Identifier; -use ockam_core::{async_trait, route, AsyncTryClone, Error, Route}; +use ockam_core::{async_trait, Error, Route, TryClone}; use ockam_multiaddr::proto::Secure; use ockam_multiaddr::{Match, MultiAddr, Protocol}; use ockam_node::Context; @@ -49,13 +49,13 @@ impl Instantiator for SecureChannelInstantiator { debug!(%secure_piece, %transport_route, "creating secure channel"); let route = local_multiaddr_to_route(&secure_piece)?; - let sc_ctx = ctx.async_try_clone().await?; + let sc_ctx = ctx.try_clone()?; let sc = node_manager .create_secure_channel_internal( &sc_ctx, //the transport route is needed to reach the secure channel listener //since it can be in another node - route![transport_route, route], + transport_route + route, &self.identifier, self.authorized_identities.clone(), None, diff --git a/implementations/rust/ockam/ockam_api/src/nodes/registry.rs b/implementations/rust/ockam/ockam_api/src/nodes/registry.rs index 099e180044c..c5d6f22e3d5 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/registry.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/registry.rs @@ -3,49 +3,56 @@ use crate::DefaultAddress; use ockam::identity::Identifier; use ockam::identity::{SecureChannel, SecureChannelListener}; -use ockam_core::compat::collections::BTreeMap; +use ockam_core::compat::collections::hash_map::Equivalent; +use ockam_core::compat::collections::HashMap; +use ockam_core::compat::sync::RwLock as SyncRwLock; use ockam_core::{Address, Route}; use ockam_multiaddr::MultiAddr; -use ockam_node::compat::asynchronous::{Mutex, RwLock}; +use ockam_node::compat::asynchronous::Mutex as AsyncMutex; use ockam_transport_core::HostnamePort; use crate::session::session::Session; -use std::borrow::Borrow; use std::fmt::Display; +use std::hash::Hash; use std::sync::Arc; #[derive(Default)] pub(crate) struct SecureChannelRegistry { - channels: RwLock>, + channels: SyncRwLock>, } impl SecureChannelRegistry { - pub async fn get_by_addr(&self, addr: &Address) -> Option { - let channels = self.channels.read().await; - channels + pub fn get_by_addr(&self, addr: &Address) -> Option { + self.channels + .read() + .unwrap() .iter() .find(|&x| x.sc.encryptor_address() == addr) .cloned() } - pub async fn insert( + pub fn insert( &self, route: Route, sc: SecureChannel, authorized_identifiers: Option>, ) { - let mut channels = self.channels.write().await; - channels.push(SecureChannelInfo::new(route, sc, authorized_identifiers)) + self.channels.write().unwrap().push(SecureChannelInfo::new( + route, + sc, + authorized_identifiers, + )) } - pub async fn remove_by_addr(&self, addr: &Address) { - let mut channels = self.channels.write().await; - channels.retain(|x| x.sc().encryptor_address() != addr) + pub fn remove_by_addr(&self, addr: &Address) { + self.channels + .write() + .unwrap() + .retain(|x| x.sc().encryptor_address() != addr) } - pub async fn list(&self) -> Vec { - let channels = self.channels.read().await; - channels.clone() + pub fn list(&self) -> Vec { + self.channels.read().unwrap().clone() } } @@ -126,7 +133,7 @@ impl KafkaServiceInfo { pub(crate) struct InletInfo { pub(crate) bind_addr: String, pub(crate) outlet_addr: MultiAddr, - pub(crate) session: Arc>, + pub(crate) session: Arc>, pub(crate) privileged: bool, } @@ -140,7 +147,7 @@ impl InletInfo { Self { bind_addr: bind_addr.to_owned(), outlet_addr, - session: Arc::new(Mutex::new(session)), + session: Arc::new(AsyncMutex::new(session)), privileged, } } @@ -171,7 +178,7 @@ impl OutletInfo { pub struct RegistryRelayInfo { pub(crate) destination_address: MultiAddr, pub(crate) alias: String, - pub(crate) session: Arc>, + pub(crate) session: Arc>, } #[derive(Default)] @@ -189,75 +196,69 @@ pub(crate) struct Registry { } pub(crate) struct RegistryOf { - map: RwLock>, + map: SyncRwLock>, } impl Default for RegistryOf { fn default() -> Self { RegistryOf { - map: RwLock::new(BTreeMap::default()), + map: Default::default(), } } } -impl RegistryOf { - pub async fn insert(&self, k: K, v: V) -> Option - where - K: Ord, - { - let mut map = self.map.write().await; - map.insert(k, v) +impl RegistryOf { + pub fn insert(&self, k: K, v: V) -> Option { + self.map.write().unwrap().insert(k, v) } - pub async fn get(&self, key: &Q) -> Option + pub fn get(&self, key: &Q) -> Option where - K: Borrow + Ord, + Q: Hash + Equivalent + ?Sized, { - let map = self.map.read().await; - map.get(key).cloned() + self.map.read().unwrap().get(key).cloned() } - pub async fn keys(&self) -> Vec { - let map = self.map.read().await; - map.clone().keys().cloned().collect() + pub fn keys(&self) -> Vec { + self.map.read().unwrap().clone().keys().cloned().collect() } - pub async fn values(&self) -> Vec { - let map = self.map.read().await; - map.clone().values().cloned().collect() + pub fn values(&self) -> Vec { + self.map.read().unwrap().values().cloned().collect() } - pub async fn entries(&self) -> Vec<(K, V)> { - let map = self.map.read().await; - map.iter().map(|(k, v)| (k.clone(), v.clone())).collect() + pub fn entries(&self) -> Vec<(K, V)> { + self.map + .read() + .unwrap() + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect() } - pub async fn remove(&self, key: &Q) -> Option + pub fn remove(&self, key: &Q) -> Option where - K: Borrow + Ord, + Q: Hash + Equivalent + ?Sized, { - let mut map = self.map.write().await; - map.remove(key) + self.map.write().unwrap().remove(key) } - pub async fn contains_key(&self, key: &Q) -> bool + pub fn contains_key(&self, key: &Q) -> bool where - Q: Ord + ?Sized, - K: Borrow + Ord, + Q: Hash + Equivalent + ?Sized, { - let map = self.map.read().await; - map.contains_key(key) + self.map.read().unwrap().contains_key(key) } } impl RegistryOf { - pub async fn generate_worker_addr(&self, worker_addr: Option
) -> Address { + pub fn generate_worker_addr(&self, worker_addr: Option
) -> Address { match worker_addr { Some(addr) => addr, None => { // If no worker address is passed, return the default address if it's not in use let default: Address = DefaultAddress::OUTLET_SERVICE.into(); - if self.contains_key(&default).await { + if self.contains_key(&default) { random_name().into() } else { default @@ -271,77 +272,69 @@ impl RegistryOf { mod tests { use super::*; - #[tokio::test] - async fn outlet_registry_generate_worker_address_start_with_none() { + #[test] + fn outlet_registry_generate_worker_address_start_with_none() { let registry = Registry::default(); // No worker address passed, should return the default address because it's not in use - let worker_addr = registry.outlets.generate_worker_addr(None).await; + let worker_addr = registry.outlets.generate_worker_addr(None); assert_eq!(worker_addr, DefaultAddress::OUTLET_SERVICE.into()); registry .outlets - .insert(worker_addr.clone(), outlet_info(worker_addr)) - .await; - assert_eq!(registry.outlets.entries().await.len(), 1); + .insert(worker_addr.clone(), outlet_info(worker_addr)); + assert_eq!(registry.outlets.entries().len(), 1); // No worker address passed, should return a random address because the default it's in use - let worker_addr = registry.outlets.generate_worker_addr(None).await; + let worker_addr = registry.outlets.generate_worker_addr(None); assert_ne!(worker_addr, DefaultAddress::OUTLET_SERVICE.into()); registry .outlets - .insert(worker_addr.clone(), outlet_info(worker_addr)) - .await; - assert_eq!(registry.outlets.entries().await.len(), 2); + .insert(worker_addr.clone(), outlet_info(worker_addr)); + assert_eq!(registry.outlets.entries().len(), 2); // Worker address passed, should return the same address let passed_addr = Address::from_string("my_outlet"); let worker_addr = registry .outlets - .generate_worker_addr(Some(passed_addr.clone())) - .await; + .generate_worker_addr(Some(passed_addr.clone())); assert_eq!(worker_addr, passed_addr.clone()); registry .outlets - .insert(worker_addr.clone(), outlet_info(worker_addr)) - .await; - assert_eq!(registry.outlets.entries().await.len(), 3); + .insert(worker_addr.clone(), outlet_info(worker_addr)); + assert_eq!(registry.outlets.entries().len(), 3); // Same worker address passed, should return the same address and not a random one let worker_addr = registry .outlets - .generate_worker_addr(Some(passed_addr.clone())) - .await; + .generate_worker_addr(Some(passed_addr.clone())); assert_eq!(worker_addr, passed_addr.clone()); } - #[tokio::test] - async fn outlet_registry_generate_worker_address_start_with_some() { + #[test] + fn outlet_registry_generate_worker_address_start_with_some() { let registry = Registry::default(); // Worker address passed, should return the same address let passed_addr = Address::from_string("my_outlet"); let worker_addr = registry .outlets - .generate_worker_addr(Some(passed_addr.clone())) - .await; + .generate_worker_addr(Some(passed_addr.clone())); assert_eq!(worker_addr, passed_addr); registry .outlets - .insert(worker_addr.clone(), outlet_info(worker_addr)) - .await; - assert_eq!(registry.outlets.entries().await.len(), 1); + .insert(worker_addr.clone(), outlet_info(worker_addr)); + assert_eq!(registry.outlets.entries().len(), 1); // No worker address passed, should return the default address because it's not in use - let worker_addr = registry.outlets.generate_worker_addr(None).await; + let worker_addr = registry.outlets.generate_worker_addr(None); assert_eq!(worker_addr, DefaultAddress::OUTLET_SERVICE.into()); registry .outlets - .insert(worker_addr.clone(), outlet_info(worker_addr)) - .await; - assert_eq!(registry.outlets.entries().await.len(), 2); + .insert(worker_addr.clone(), outlet_info(worker_addr)); + assert_eq!(registry.outlets.entries().len(), 2); // No worker address passed, should return a random address because the default it's in use - let worker_addr = registry.outlets.generate_worker_addr(None).await; + let worker_addr = registry.outlets.generate_worker_addr(None); assert_ne!(worker_addr, DefaultAddress::OUTLET_SERVICE.into()); } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/background_node_client.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/background_node_client.rs index 3c37dc8e94c..6e1a836e767 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/background_node_client.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/background_node_client.rs @@ -44,15 +44,15 @@ impl BackgroundNodeClient { Some(name) => name, None => cli_state.get_default_node().await?.name(), }; - Self::create_to_node(ctx, cli_state, &node_name).await + Self::create_to_node(ctx, cli_state, &node_name) } - pub async fn create_to_node( + pub fn create_to_node( ctx: &Context, cli_state: &CliState, node_name: &str, ) -> miette::Result { - let tcp_transport = TcpTransport::create(ctx).await.into_diagnostic()?; + let tcp_transport = TcpTransport::create(ctx).into_diagnostic()?; BackgroundNodeClient::new(&tcp_transport, cli_state, node_name) } @@ -140,7 +140,7 @@ impl BackgroundNodeClient { .success() .into_diagnostic(); - let _ = tcp_connection.stop(ctx).await; + let _ = tcp_connection.stop(ctx); res } @@ -158,7 +158,7 @@ impl BackgroundNodeClient { let (tcp_connection, client) = self.make_client().await?; let res = client.ask(ctx, req).await.into_diagnostic(); - let _ = tcp_connection.stop(ctx).await; + let _ = tcp_connection.stop(ctx); res } @@ -175,7 +175,7 @@ impl BackgroundNodeClient { .success() .into_diagnostic(); - let _ = tcp_connection.stop(ctx).await; + let _ = tcp_connection.stop(ctx); res } @@ -191,7 +191,7 @@ impl BackgroundNodeClient { let (tcp_connection, client) = self.make_client().await?; let res = client.tell(ctx, req).await.into_diagnostic(); - let _ = tcp_connection.stop(ctx).await; + let _ = tcp_connection.stop(ctx); res } @@ -200,19 +200,13 @@ impl BackgroundNodeClient { self.create_tcp_connection() .await? .stop(ctx) - .await .into_diagnostic() } /// Make a route to the node and connect using TCP async fn create_route(&self) -> miette::Result<(TcpConnection, Route)> { let tcp_connection = self.create_tcp_connection().await?; - let route = self - .to - .clone() - .modify() - .prepend(tcp_connection.sender_address().clone()) - .into(); + let route = tcp_connection.sender_address().clone() + self.to.clone(); debug!("Sending requests to {route}"); Ok((tcp_connection, route)) } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/flow_controls.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/flow_controls.rs index 247e73f4c48..55e3ff55beb 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/flow_controls.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/flow_controls.rs @@ -50,7 +50,7 @@ impl NodeManager { return Ok(Some(AddConsumerError::InvalidAddress(consumer.clone()))); }; - ctx.flow_controls().add_consumer(address, flow_control_id); + ctx.flow_controls().add_consumer(&address, flow_control_id); Ok(None) } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/http.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/http.rs index 97775d51dfd..3b98e00ba6a 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/http.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/http.rs @@ -48,8 +48,7 @@ impl HttpServer { }; ProcessorBuilder::new(processor) .with_address(Address::random_tagged("node_http_server")) - .start(context) - .await?; + .start(context)?; info!("HTTP server listening on: {addr:?}"); Ok(addr) } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/in_memory_node.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/in_memory_node.rs index a626603f779..7e3920d8c38 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/in_memory_node.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/in_memory_node.rs @@ -134,7 +134,7 @@ impl InMemoryNode { ) -> miette::Result { let defaults = NodeManagerDefaults::default(); - let tcp = TcpTransport::create(ctx).await.into_diagnostic()?; + let tcp = TcpTransport::create(ctx).into_diagnostic()?; let tcp_listener = tcp .listen( defaults.tcp_listener_address.as_str(), @@ -173,7 +173,7 @@ impl InMemoryNode { .await .into_diagnostic()?; ctx.flow_controls() - .add_consumer(NODEMANAGER_ADDR, tcp_listener.flow_control_id()); + .add_consumer(&NODEMANAGER_ADDR.into(), tcp_listener.flow_control_id()); Ok(node_manager) } @@ -183,16 +183,16 @@ impl InMemoryNode { } pub async fn stop(&self, ctx: &Context) -> Result<()> { - for session in self.registry.inlets.values().await { + for session in self.registry.inlets.values() { session.session.lock().await.stop().await; } - for session in self.registry.relays.values().await { + for session in self.registry.relays.values() { session.session.lock().await.stop().await; } for addr in DefaultAddress::iter() { - let result = ctx.stop_worker(addr).await; + let result = ctx.stop_address(&addr.into()); // when stopping we can safely ignore missing services if let Err(err) = result { if err.code().kind == Kind::NotFound { diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/kafka_services.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/kafka_services.rs index 05ed74d73d0..527378d8a4f 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/kafka_services.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/kafka_services.rs @@ -240,17 +240,13 @@ impl InMemoryNode { encrypted_fields, )), Arc::new(policy_access_control.create_incoming()), - Arc::new(policy_access_control.create_outgoing(context).await?), - ) - .await?; + Arc::new(policy_access_control.create_outgoing(context)?), + )?; - self.registry - .kafka_services - .insert( - interceptor_address, - KafkaServiceInfo::new(KafkaServiceKind::Inlet), - ) - .await; + self.registry.kafka_services.insert( + interceptor_address, + KafkaServiceInfo::new(KafkaServiceKind::Inlet), + ); Ok(()) } @@ -295,24 +291,26 @@ impl InMemoryNode { outlet_controller.clone(), spawner_flow_control_id.clone(), )), - Arc::new(policy_access_control.create_outgoing(context).await?), + Arc::new(policy_access_control.create_outgoing(context)?), Arc::new(policy_access_control.create_incoming()), - ) - .await?; + )?; // every secure channel can reach this service let flow_controls = context.flow_controls(); flow_controls.add_consumer( - interceptor_address.clone(), + &interceptor_address, &default_secure_channel_listener_flow_control_id, ); // this spawner flow control id is used to control communication with dynamically created // outlets - flow_controls.add_spawner(interceptor_address.clone(), &spawner_flow_control_id); + flow_controls.add_spawner(&interceptor_address, &spawner_flow_control_id); // allow communication with the kafka bootstrap outlet - flow_controls.add_consumer(KAFKA_OUTLET_BOOTSTRAP_ADDRESS, &spawner_flow_control_id); + flow_controls.add_consumer( + &KAFKA_OUTLET_BOOTSTRAP_ADDRESS.into(), + &spawner_flow_control_id, + ); self.create_outlet( context, @@ -325,13 +323,10 @@ impl InMemoryNode { ) .await?; - self.registry - .kafka_services - .insert( - service_address, - KafkaServiceInfo::new(KafkaServiceKind::Outlet), - ) - .await; + self.registry.kafka_services.insert( + service_address, + KafkaServiceInfo::new(KafkaServiceKind::Outlet), + ); Ok(()) } @@ -345,20 +340,20 @@ impl InMemoryNode { kind: KafkaServiceKind, ) -> Result { debug!(address = %address, kind = %kind, "Deleting kafka service"); - match self.registry.kafka_services.get(&address).await { + match self.registry.kafka_services.get(&address) { None => Ok(DeleteKafkaServiceResult::ServiceNotFound { address, kind }), Some(e) => { if kind.eq(e.kind()) { match e.kind() { KafkaServiceKind::Inlet => { - ctx.stop_worker(address.clone()).await?; + ctx.stop_address(&address)?; } KafkaServiceKind::Outlet => { - ctx.stop_worker(KAFKA_OUTLET_INTERCEPTOR_ADDRESS).await?; - ctx.stop_worker(KAFKA_OUTLET_BOOTSTRAP_ADDRESS).await?; + ctx.stop_address(&KAFKA_OUTLET_INTERCEPTOR_ADDRESS.into())?; + ctx.stop_address(&KAFKA_OUTLET_BOOTSTRAP_ADDRESS.into())?; } } - self.registry.kafka_services.remove(&address).await; + self.registry.kafka_services.remove(&address); Ok(DeleteKafkaServiceResult::ServiceDeleted) } else { error!(address = %address, "Service is not a kafka {}", kind.to_string()); diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/manager.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/manager.rs index fbe0d18bbe4..f4ea14edbbd 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/manager.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/manager.rs @@ -33,8 +33,8 @@ use ockam_abac::{ }; use ockam_core::flow_control::FlowControlId; use ockam_core::{ - route, AllowAll, AsyncTryClone, CachedIncomingAccessControl, CachedOutgoingAccessControl, - IncomingAccessControl, OutgoingAccessControl, + route, AllowAll, CachedIncomingAccessControl, CachedOutgoingAccessControl, + IncomingAccessControl, OutgoingAccessControl, TryClone, }; use ockam_multiaddr::MultiAddr; use ockam_node::Context; @@ -99,7 +99,7 @@ impl NodeManager { } NodeManagerCredentialRetrieverOptions::Remote { info, scope } => { Some(Arc::new(RemoteCredentialRetrieverCreator::new( - ctx.async_try_clone().await?, + ctx.try_clone()?, Arc::new(transport_options.tcp_transport.clone()), secure_channels.clone(), info.clone(), @@ -124,7 +124,7 @@ impl NodeManager { } NodeManagerCredentialRetrieverOptions::Remote { info, scope } => { Some(Arc::new(RemoteCredentialRetrieverCreator::new( - ctx.async_try_clone().await?, + ctx.try_clone()?, Arc::new(transport_options.tcp_transport.clone()), secure_channels.clone(), info.clone(), @@ -183,17 +183,16 @@ impl NodeManager { udp_transport, rendezvous_route, options, - ) - .await?; + )?; if let Some(api_sc_listener) = &s.api_sc_listener { ctx.flow_controls().add_consumer( - DefaultAddress::RENDEZVOUS_SERVICE, + &DefaultAddress::RENDEZVOUS_SERVICE.into(), api_sc_listener.flow_control_id(), ); ctx.flow_controls() - .add_consumer(api_sc_listener.address().clone(), &flow_control_id); + .add_consumer(api_sc_listener.address(), &flow_control_id); } } @@ -208,10 +207,11 @@ impl NodeManager { api_flow_control_id: &FlowControlId, ) -> ockam_core::Result { // Start services - ctx.flow_controls() - .add_consumer(DefaultAddress::UPPERCASE_SERVICE, api_flow_control_id); - self.start_uppercase_service_impl(ctx, DefaultAddress::UPPERCASE_SERVICE.into()) - .await?; + ctx.flow_controls().add_consumer( + &DefaultAddress::UPPERCASE_SERVICE.into(), + api_flow_control_id, + ); + self.start_uppercase_service_impl(ctx, DefaultAddress::UPPERCASE_SERVICE.into())?; let secure_channel_listener = self .create_secure_channel_listener( @@ -254,7 +254,7 @@ impl NodeManager { options }; - RelayService::create(ctx, DefaultAddress::RELAY_SERVICE, options).await?; + RelayService::create(ctx, DefaultAddress::RELAY_SERVICE, options)?; Ok(secure_channel_listener) } @@ -276,7 +276,7 @@ impl NodeManager { // Always start the echoer service as ockam_api::Session assumes it will be // started unconditionally on every node. It's used for liveliness checks. ctx.flow_controls() - .add_consumer(DefaultAddress::ECHO_SERVICE, &api_flow_control_id); + .add_consumer(&DefaultAddress::ECHO_SERVICE.into(), &api_flow_control_id); self.start_echoer_service(ctx, DefaultAddress::ECHO_SERVICE.into()) .await?; @@ -373,11 +373,10 @@ impl NodeManager { &self.tcp_transport } - pub async fn list_outlets(&self) -> Vec { + pub fn list_outlets(&self) -> Vec { self.registry .outlets .entries() - .await .iter() .map(|(_, info)| { OutletStatus::new( @@ -539,7 +538,7 @@ impl NodeManager { .await?; let incoming_ac = policy_access_control.create_incoming(); - let outgoing_ac = policy_access_control.create_outgoing(ctx).await?; + let outgoing_ac = policy_access_control.create_outgoing(ctx)?; cfg_if::cfg_if! { if #[cfg(feature = "std")] { diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/node_services.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/node_services.rs index 27a11c0ad6e..34059ded8c0 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/node_services.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/node_services.rs @@ -20,7 +20,7 @@ use crate::uppercase::Uppercase; use super::NodeManagerWorker; impl NodeManagerWorker { - pub(super) async fn start_uppercase_service( + pub(super) fn start_uppercase_service( &self, ctx: &Context, request: StartUppercaseServiceRequest, @@ -28,7 +28,6 @@ impl NodeManagerWorker { match self .node_manager .start_uppercase_service_impl(ctx, request.addr.into()) - .await { Ok(_) => Ok(Response::ok()), Err(e) => Err(Response::internal_error_no_request(&e.to_string())), @@ -50,7 +49,7 @@ impl NodeManagerWorker { } } - pub(super) async fn start_hop_service( + pub(super) fn start_hop_service( &self, ctx: &Context, request: StartHopServiceRequest, @@ -58,28 +57,25 @@ impl NodeManagerWorker { match self .node_manager .start_hop_service(ctx, request.addr.into()) - .await { Ok(_) => Ok(Response::ok()), Err(e) => Err(Response::internal_error_no_request(&e.to_string())), } } - pub(super) async fn list_services_of_type( + pub(super) fn list_services_of_type( &self, service_type: &str, ) -> Result>, Response> { - match self.node_manager.list_services_of_type(service_type).await { + match self.node_manager.list_services_of_type(service_type) { Ok(Either::Left(services)) => Ok(Response::ok().body(services)), Ok(Either::Right(message)) => Err(Response::bad_request_no_request(&message)), Err(e) => Err(Response::internal_error_no_request(&e.to_string())), } } - pub(super) async fn list_services( - &self, - ) -> Result>, Response> { - Ok(Response::ok().body(self.node_manager.list_services().await)) + pub(super) fn list_services(&self) -> Result>, Response> { + Ok(Response::ok().body(self.node_manager.list_services())) } #[instrument(skip_all)] @@ -102,7 +98,7 @@ impl NodeManagerWorker { } impl NodeManager { - pub async fn list_services_of_type( + pub fn list_services_of_type( &self, service_type: &str, ) -> Result, String>> { @@ -111,7 +107,7 @@ impl NodeManager { "the service {service_type} is not a valid service" ))); }; - let services = self.list_services().await; + let services = self.list_services(); Ok(Either::Left( services .into_iter() @@ -120,12 +116,11 @@ impl NodeManager { )) } - pub async fn list_services(&self) -> Vec { + pub fn list_services(&self) -> Vec { let mut list = Vec::new(); self.registry .uppercase_services .keys() - .await .iter() .for_each(|addr| { list.push(ServiceStatus::new( @@ -136,7 +131,6 @@ impl NodeManager { self.registry .echoer_services .keys() - .await .iter() .for_each(|addr| { list.push(ServiceStatus::new( @@ -144,21 +138,15 @@ impl NodeManager { DefaultAddress::ECHO_SERVICE, )) }); - self.registry - .hop_services - .keys() - .await - .iter() - .for_each(|addr| { - list.push(ServiceStatus::new( - addr.address(), - DefaultAddress::HOP_SERVICE, - )) - }); + self.registry.hop_services.keys().iter().for_each(|addr| { + list.push(ServiceStatus::new( + addr.address(), + DefaultAddress::HOP_SERVICE, + )) + }); self.registry .kafka_services .entries() - .await .iter() .for_each(|(address, info)| { list.push(ServiceStatus::new( @@ -172,39 +160,32 @@ impl NodeManager { list } - pub(super) async fn start_uppercase_service_impl( - &self, - ctx: &Context, - addr: Address, - ) -> Result<()> { - if self.registry.uppercase_services.contains_key(&addr).await { + pub(super) fn start_uppercase_service_impl(&self, ctx: &Context, addr: Address) -> Result<()> { + if self.registry.uppercase_services.contains_key(&addr) { return Err(ApiError::core(format!( "uppercase service already exists at {addr}" ))); } - ctx.start_worker(addr.clone(), Uppercase).await?; + ctx.start_worker(addr.clone(), Uppercase)?; info!("uppercase service was initialized at {addr}"); self.registry .uppercase_services - .insert(addr.clone(), Default::default()) - .await; + .insert(addr.clone(), Default::default()); Ok(()) } pub(super) async fn start_echoer_service(&self, ctx: &Context, addr: Address) -> Result<()> { - if self.registry.echoer_services.contains_key(&addr).await { + if self.registry.echoer_services.contains_key(&addr) { return Err(ApiError::core(format!( "echoer service already exists at {addr}" ))); } - if ctx.is_worker_registered_at(&addr) { - ctx.stop_worker(addr.clone()).await? - }; + _ = ctx.stop_address(&addr); let (incoming_ac, outgoing_ac) = self .access_control( @@ -220,37 +201,32 @@ impl NodeManager { .with_address(addr.clone()) .with_incoming_access_control_arc(incoming_ac) .with_outgoing_access_control_arc(outgoing_ac) - .start(ctx) - .await?; + .start(ctx)?; info!("echoer service was initialized at {addr}"); self.registry .echoer_services - .insert(addr, Default::default()) - .await; + .insert(addr, Default::default()); Ok(()) } - pub(super) async fn start_hop_service(&self, ctx: &Context, addr: Address) -> Result<()> { - if self.registry.hop_services.contains_key(&addr).await { + pub(super) fn start_hop_service(&self, ctx: &Context, addr: Address) -> Result<()> { + if self.registry.hop_services.contains_key(&addr) { return Err(ApiError::core(format!( "hop service already exists at {addr}" ))); } ctx.flow_controls() - .add_consumer(addr.clone(), &self.api_transport_flow_control_id); + .add_consumer(&addr, &self.api_transport_flow_control_id); - ctx.start_worker(addr.clone(), Hop).await?; + ctx.start_worker(addr.clone(), Hop)?; info!("hop service was initialized at {addr}"); - self.registry - .hop_services - .insert(addr, Default::default()) - .await; + self.registry.hop_services.insert(addr, Default::default()); Ok(()) } @@ -267,10 +243,10 @@ impl NodeManager { .get_named_identity_by_identifier(&self.node_identifier) .await?; let transports = self.get_tcp_listeners(); - let listeners = self.list_secure_channel_listeners().await; + let listeners = self.list_secure_channel_listeners(); let inlets = self.list_inlets().await; - let outlets = self.list_outlets().await; - let services = self.list_services().await; + let outlets = self.list_outlets(); + let services = self.list_services(); NodeResources::from_parts( node, identity.name(), diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/relay.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/relay.rs index af7b3429da1..d29fa084f18 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/relay.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/relay.rs @@ -9,8 +9,9 @@ use ockam::remote::{RemoteRelay, RemoteRelayOptions}; use ockam::Result; use ockam_core::api::{Error, Request, RequestHeader, Response}; use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{async_trait, route, Address, AsyncTryClone}; +use ockam_core::{async_trait, Address, TryClone}; use ockam_multiaddr::MultiAddr; +use ockam_node::compat::asynchronous::Mutex as AsyncMutex; use ockam_node::compat::asynchronous::Mutex; use ockam_node::Context; @@ -109,7 +110,7 @@ impl NodeManager { /// registered on this node pub async fn get_relays(&self) -> Vec { let mut relays = vec![]; - for (_, registry_info) in self.registry.relays.entries().await { + for (_, registry_info) in self.registry.relays.entries() { let session = registry_info.session.lock().await; let info = RelayInfo::from_session( &session, @@ -136,7 +137,7 @@ impl NodeManager { relay_address: Option, return_timing: ReturnTiming, ) -> Result { - if self.registry.relays.contains_key(&alias).await { + if self.registry.relays.contains_key(&alias) { let message = format!("A relay with the name '{alias}' already exists"); return Err(ockam_core::Error::new( Origin::Node, @@ -147,7 +148,7 @@ impl NodeManager { let replacer = RelaySessionReplacer { node_manager: Arc::downgrade(self), - context: ctx.async_try_clone().await?, + context: ctx.try_clone()?, addr: addr.clone(), relay_address, connection: None, @@ -155,7 +156,7 @@ impl NodeManager { authorized, }; - let mut session = Session::create(ctx, Arc::new(Mutex::new(replacer)), None).await?; + let mut session = Session::create(ctx, Arc::new(Mutex::new(replacer)), None)?; let remote_relay_info = match return_timing { ReturnTiming::Immediately => None, @@ -180,7 +181,7 @@ impl NodeManager { } }; - session.start_monitoring().await?; + session.start_monitoring()?; let relay_info = RelayInfo::new(addr.clone(), alias.clone(), session.connection_status()); let relay_info = if let Some(remote_relay_info) = remote_relay_info { @@ -197,13 +198,12 @@ impl NodeManager { let registry_relay_info = RegistryRelayInfo { destination_address: addr.clone(), alias: alias.clone(), - session: Arc::new(Mutex::new(session)), + session: Arc::new(AsyncMutex::new(session)), }; self.registry .relays - .insert(alias, registry_relay_info.clone()) - .await; + .insert(alias, registry_relay_info.clone()); Ok(relay_info) } @@ -212,7 +212,7 @@ impl NodeManager { /// /// This function removes a relay from the node registry and stops the relay worker. pub async fn delete_relay_impl(&self, alias: &str) -> Result<(), ockam::Error> { - if let Some(relay_to_delete) = self.registry.relays.remove(alias).await { + if let Some(relay_to_delete) = self.registry.relays.remove(alias) { debug!(%alias, "Successfully removed relay from node registry"); relay_to_delete.session.lock().await.stop().await; debug!(%alias, "Successfully stopped relay"); @@ -235,7 +235,7 @@ impl NodeManager { alias: &str, ) -> Result, Response> { debug!("Handling ShowRelay request"); - if let Some(registry_info) = self.registry.relays.get(alias).await { + if let Some(registry_info) = self.registry.relays.get(alias) { let session = registry_info.session.lock().await; let relay_info = RelayInfo::from_session( @@ -321,7 +321,7 @@ impl SessionReplacer for RelaySessionReplacer { // Add all Hop workers as consumers for Demo purposes // Production nodes should not run any Hop workers - for hop in node_manager.registry.hop_services.keys().await { + for hop in node_manager.registry.hop_services.keys() { connection.add_consumer(&self.context, &hop); } @@ -337,10 +337,9 @@ impl SessionReplacer for RelaySessionReplacer { self.relay_worker_address = Some(relay_info.worker_address().clone()); // ping directly the other node - let ping_route = route![connection.transport_route()]; Ok(ReplacerOutcome { - ping_route, + ping_route: connection.transport_route(), kind: ReplacerOutputKind::Relay(relay_info), }) } @@ -354,14 +353,14 @@ impl SessionReplacer for RelaySessionReplacer { }; if let Some(connection) = self.connection.take() { - let result = connection.close(&self.context, &node_manager).await; + let result = connection.close(&self.context, &node_manager); if let Err(err) = result { error!(?err, "Failed to close connection"); } } if let Some(relay_address) = self.relay_worker_address.take() { - match self.context.stop_worker(relay_address.clone()).await { + match self.context.stop_address(&relay_address) { Ok(_) => { debug!(%relay_address, "Successfully stopped relay"); } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/secure_channel.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/secure_channel.rs index 916fc710ce6..9c26bebfd63 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/secure_channel.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/secure_channel.rs @@ -37,8 +37,8 @@ pub enum SecureChannelType { /// SECURE CHANNELS impl NodeManagerWorker { - pub async fn list_secure_channels(&self) -> Result>, Response> { - Ok(Response::ok().body(self.node_manager.list_secure_channels().await)) + pub fn list_secure_channels(&self) -> Result>, Response> { + Ok(Response::ok().body(self.node_manager.list_secure_channels())) } pub(super) async fn create_secure_channel( @@ -73,7 +73,7 @@ impl NodeManagerWorker { Ok(response) } - pub async fn delete_secure_channel( + pub fn delete_secure_channel( &self, delete_secure_channel: DeleteSecureChannelRequest, ctx: &Context, @@ -85,24 +85,22 @@ impl NodeManagerWorker { let response = self .node_manager .delete_secure_channel(ctx, &address) - .await .map(|_| Response::ok().body(DeleteSecureChannelResponse::new(Some(address))))?; Ok(response) } - pub async fn show_secure_channel( + pub fn show_secure_channel( &self, show_secure_channel: ShowSecureChannelRequest, ) -> Result, Response> { let ShowSecureChannelRequest { channel: address } = show_secure_channel; - let response = - self.node_manager - .get_secure_channel(&address) - .await - .map(|secure_channel| { - Response::ok().body(ShowSecureChannelResponse::new(Some(secure_channel))) - })?; + let response = self + .node_manager + .get_secure_channel(&address) + .map(|secure_channel| { + Response::ok().body(ShowSecureChannelResponse::new(Some(secure_channel))) + })?; Ok(response) } @@ -136,7 +134,7 @@ impl NodeManagerWorker { Ok(response) } - pub async fn delete_secure_channel_listener( + pub fn delete_secure_channel_listener( &self, delete_secure_channel_listener: DeleteSecureChannelListenerRequest, ctx: &Context, @@ -146,23 +144,22 @@ impl NodeManagerWorker { let response = self .node_manager .delete_secure_channel_listener(ctx, &addr) - .await .map(|_| Response::ok().body(DeleteSecureChannelListenerResponse::new(addr)))?; Ok(response) } - pub async fn show_secure_channel_listener( + pub fn show_secure_channel_listener( &self, show_secure_channel_listener: ShowSecureChannelListenerRequest, ) -> Result, Response> { let ShowSecureChannelListenerRequest { addr } = show_secure_channel_listener; - Ok(Response::ok().body(self.node_manager.get_secure_channel_listener(&addr).await?)) + Ok(Response::ok().body(self.node_manager.get_secure_channel_listener(&addr)?)) } - pub async fn list_secure_channel_listener( + pub fn list_secure_channel_listener( &self, ) -> Result>, Response> { - Ok(Response::ok().body(self.node_manager.list_secure_channel_listeners().await)) + Ok(Response::ok().body(self.node_manager.list_secure_channel_listeners())) } } @@ -256,32 +253,30 @@ impl NodeManager { self.registry .secure_channels - .insert(sc_route, sc.clone(), authorized_identifiers) - .await; + .insert(sc_route, sc.clone(), authorized_identifiers); Ok(sc) } - pub async fn delete_secure_channel(&self, ctx: &Context, addr: &Address) -> Result<()> { + pub fn delete_secure_channel(&self, ctx: &Context, addr: &Address) -> Result<()> { debug!(%addr, "deleting secure channel"); - if (self.registry.secure_channels.get_by_addr(addr).await).is_none() { + if self.registry.secure_channels.get_by_addr(addr).is_none() { return Err(ockam_core::Error::new( Origin::Api, Kind::NotFound, format!("Secure channel with address, {}, not found", addr), )); } - self.secure_channels.stop_secure_channel(ctx, addr).await?; - self.registry.secure_channels.remove_by_addr(addr).await; + self.secure_channels.stop_secure_channel(ctx, addr)?; + self.registry.secure_channels.remove_by_addr(addr); Ok(()) } - pub async fn get_secure_channel(&self, addr: &Address) -> Result { + pub fn get_secure_channel(&self, addr: &Address) -> Result { debug!(%addr, "On show secure channel"); self.registry .secure_channels .get_by_addr(addr) - .await .ok_or_else(|| { ockam_core::Error::new( Origin::Api, @@ -291,9 +286,9 @@ impl NodeManager { }) } - pub async fn list_secure_channels(&self) -> Vec { + pub fn list_secure_channels(&self) -> Vec { let registry = &self.registry.secure_channels; - let secure_channel_list = registry.list().await; + let secure_channel_list = registry.list(); secure_channel_list .into_iter() .map(|secure_channel| secure_channel.sc().encryptor_address().to_string()) @@ -309,7 +304,7 @@ impl NodeManager { address: Address, ) -> Result { // skip creation if it already exists - if let Some(listener) = self.registry.secure_channel_listeners.get(&address).await { + if let Some(listener) = self.registry.secure_channel_listeners.get(&address) { return Ok(listener); } @@ -379,35 +374,39 @@ impl NodeManager { options }; - let listener = secure_channels - .create_secure_channel_listener(ctx, &identifier, address.clone(), options) - .await?; + let listener = secure_channels.create_secure_channel_listener( + ctx, + &identifier, + address.clone(), + options, + )?; info!("Secure channel listener was initialized at {address}"); self.registry .secure_channel_listeners - .insert(address.clone(), listener.clone()) - .await; + .insert(address.clone(), listener.clone()); if secure_channel_type == SecureChannelType::KeyExchangeAndMessages { // TODO: Clean // Add Echoer as a consumer by default - ctx.flow_controls() - .add_consumer(DefaultAddress::ECHO_SERVICE, listener.flow_control_id()); + ctx.flow_controls().add_consumer( + &DefaultAddress::ECHO_SERVICE.into(), + listener.flow_control_id(), + ); // TODO: PUNCTURE Make optional? ctx.flow_controls().add_consumer( - DefaultAddress::UDP_PUNCTURE_NEGOTIATION_LISTENER, + &DefaultAddress::UDP_PUNCTURE_NEGOTIATION_LISTENER.into(), listener.flow_control_id(), ); // Add ourselves to allow tunneling ctx.flow_controls() - .add_consumer(address, listener.flow_control_id()); + .add_consumer(&address, listener.flow_control_id()); ctx.flow_controls().add_consumer( - DefaultAddress::UPPERCASE_SERVICE, + &DefaultAddress::UPPERCASE_SERVICE.into(), listener.flow_control_id(), ); } @@ -415,17 +414,16 @@ impl NodeManager { Ok(listener) } - pub async fn delete_secure_channel_listener( + pub fn delete_secure_channel_listener( &self, ctx: &Context, addr: &Address, ) -> Result { debug!("deleting secure channel listener: {addr}"); - ctx.stop_worker(addr.clone()).await?; + ctx.stop_address(addr)?; self.registry .secure_channel_listeners .remove(addr) - .await .ok_or_else(|| { ockam_core::Error::new( Origin::Api, @@ -435,15 +433,11 @@ impl NodeManager { }) } - pub async fn get_secure_channel_listener( - &self, - addr: &Address, - ) -> Result { + pub fn get_secure_channel_listener(&self, addr: &Address) -> Result { debug!(%addr, "On show secure channel listener"); self.registry .secure_channel_listeners .get(addr) - .await .ok_or_else(|| { ockam_core::Error::new( Origin::Api, @@ -453,9 +447,8 @@ impl NodeManager { }) } - pub async fn list_secure_channel_listeners(&self) -> Vec { - let registry = &self.registry.secure_channel_listeners; - registry.values().await + pub fn list_secure_channel_listeners(&self) -> Vec { + self.registry.secure_channel_listeners.values() } } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_inlets/node_manager.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_inlets/node_manager.rs index e801b3079e4..e243e98ad66 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_inlets/node_manager.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_inlets/node_manager.rs @@ -6,7 +6,7 @@ use ockam::identity::Identifier; use ockam::Result; use ockam_abac::{PolicyExpression, Resource, ResourceType}; use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{AsyncTryClone, Route}; +use ockam_core::{Route, TryClone}; use ockam_multiaddr::MultiAddr; use ockam_node::compat::asynchronous::Mutex; use ockam_node::Context; @@ -82,7 +82,7 @@ impl NodeManager { let registry = &self.registry.inlets; // Check that there is no entry in the registry with the same alias - if registry.contains_key(&alias).await { + if registry.contains_key(&alias) { let message = format!("A TCP inlet with alias '{alias}' already exists"); return Err(ockam_core::Error::new( Origin::Node, @@ -94,7 +94,6 @@ impl NodeManager { // Check that there is no entry in the registry with the same TCP bind address if registry .values() - .await .iter() .any(|inlet| inlet.bind_addr == listen_addr.to_string()) { @@ -111,7 +110,7 @@ impl NodeManager { let replacer = InletSessionReplacer { node_manager: Arc::downgrade(self), udp_transport, - context: ctx.async_try_clone().await?, + context: ctx.try_clone()?, listen_addr: listen_addr.to_string(), outlet_addr: outlet_addr.clone(), prefix_route, @@ -156,7 +155,7 @@ impl NodeManager { None }; - let mut session = Session::create(ctx, main_replacer, additional_session_options).await?; + let mut session = Session::create(ctx, main_replacer, additional_session_options)?; let outcome = if wait_connection { let result = session @@ -182,20 +181,17 @@ impl NodeManager { let connection_status = session.connection_status(); - session.start_monitoring().await?; + session.start_monitoring()?; - self.registry - .inlets - .insert( - alias.clone(), - InletInfo::new( - &listen_addr.to_string(), - outlet_addr.clone(), - session, - privileged, - ), - ) - .await; + self.registry.inlets.insert( + alias.clone(), + InletInfo::new( + &listen_addr.to_string(), + outlet_addr.clone(), + session, + privileged, + ), + ); let tcp_inlet_status = InletStatus::new( listen_addr.to_string(), @@ -215,7 +211,7 @@ impl NodeManager { pub async fn delete_inlet(&self, alias: &str) -> Result { info!(%alias, "Handling request to delete inlet portal"); - if let Some(inlet_to_delete) = self.registry.inlets.remove(alias).await { + if let Some(inlet_to_delete) = self.registry.inlets.remove(alias) { debug!(%alias, "Successfully removed inlet from node registry"); inlet_to_delete.session.lock().await.stop().await; self.resources().delete_resource(&alias.into()).await?; @@ -245,7 +241,7 @@ impl NodeManager { pub async fn show_inlet(&self, alias: &str) -> Option { info!(%alias, "Handling request to show inlet portal"); - if let Some(inlet_info) = self.registry.inlets.get(alias).await { + if let Some(inlet_info) = self.registry.inlets.get(alias) { let session = inlet_info.session.lock().await; let connection_status = session.connection_status(); let outcome = session.last_outcome(); @@ -290,7 +286,7 @@ impl NodeManager { pub async fn list_inlets(&self) -> Vec { let mut res = vec![]; - for (alias, info) in self.registry.inlets.entries().await { + for (alias, info) in self.registry.inlets.entries() { let session = info.session.lock().await; let connection_status = session.connection_status(); let outcome = session.last_outcome(); diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_inlets/session_replacer.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_inlets/session_replacer.rs index 9fb91fe0052..815c31a4ff3 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_inlets/session_replacer.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_inlets/session_replacer.rs @@ -127,8 +127,8 @@ impl InletSessionReplacer { } async fn create_impl(&mut self, node_manager: &NodeManager) -> Result { - self.pause_inlet().await; - self.close_connection(node_manager).await; + self.pause_inlet(); + self.close_connection(node_manager); let connection = node_manager .make_connection( @@ -146,11 +146,8 @@ impl InletSessionReplacer { let transport_route = connection.transport_route(); //we expect a fully normalized MultiAddr - let normalized_route = route![ - self.prefix_route.clone(), - connection_route.clone(), - self.suffix_route.clone() - ]; + let normalized_route = + self.prefix_route.clone() + connection_route + self.suffix_route.clone(); // Drop the last address as it will be appended automatically under the hood let normalized_stripped_route: Route = normalized_route.clone().modify().pop_back().into(); @@ -158,9 +155,7 @@ impl InletSessionReplacer { // Finally, attempt to create/update inlet using the new route let inlet_address = match self.inlet.clone() { Some(inlet) => { - inlet - .unpause(&self.context, normalized_stripped_route.clone()) - .await?; + inlet.unpause(&self.context, normalized_stripped_route.clone())?; inlet.processor_address().cloned() } @@ -213,16 +208,16 @@ impl InletSessionReplacer { }) } - async fn pause_inlet(&mut self) { + fn pause_inlet(&mut self) { if let Some(inlet) = self.inlet.as_mut() { - inlet.pause().await; + inlet.pause(); } } - async fn close_inlet(&mut self) { + fn close_inlet(&mut self) { if let Some(inlet) = self.inlet.take() { // The previous inlet worker needs to be stopped: - let result = inlet.stop(&self.context).await; + let result = inlet.stop(&self.context); if let Err(err) = result { error!( @@ -234,9 +229,9 @@ impl InletSessionReplacer { } } - async fn close_connection(&mut self, node_manager: &NodeManager) { + fn close_connection(&mut self, node_manager: &NodeManager) { if let Some(connection) = self.connection.take() { - let result = connection.close(&self.context, node_manager).await; + let result = connection.close(&self.context, node_manager); if let Err(err) = result { error!(?err, "Failed to close connection"); } @@ -290,8 +285,8 @@ impl SessionReplacer for InletSessionReplacer { return; }; - self.close_inlet().await; - self.close_connection(&node_manager).await; + self.close_inlet(); + self.close_connection(&node_manager); } } @@ -342,8 +337,7 @@ impl AdditionalSessionReplacer for InletSessionReplacer { let main_route: Route = main_route.modify().pop_back().into(); - let additional_sc_route = - route![main_route.clone(), DefaultAddress::SECURE_CHANNEL_LISTENER]; + let additional_sc_route = main_route.clone() + DefaultAddress::SECURE_CHANNEL_LISTENER; let additional_sc = node_manager .create_secure_channel_internal( @@ -368,10 +362,7 @@ impl AdditionalSessionReplacer for InletSessionReplacer { let puncture = UdpPunctureNegotiation::start_negotiation( &self.context, - route![ - main_route.clone(), - DefaultAddress::UDP_PUNCTURE_NEGOTIATION_LISTENER - ], + main_route + DefaultAddress::UDP_PUNCTURE_NEGOTIATION_LISTENER, &udp_transport, rendezvous_route, // TODO: Have a dedicated timeout @@ -388,7 +379,7 @@ impl AdditionalSessionReplacer for InletSessionReplacer { additional_sc.update_remote_node_route(route![puncture.sender_address()])?; let new_route = route![additional_sc.clone()]; - inlet.unpause(&self.context, new_route.clone()).await?; + inlet.unpause(&self.context, new_route.clone())?; self.additional_route = Some(new_route.clone()); @@ -402,20 +393,20 @@ impl AdditionalSessionReplacer for InletSessionReplacer { match self.main_route.as_ref() { Some(main_route) if enable_fallback => { // Switch Inlet to the main route - let res = inlet.unpause(&self.context, main_route.clone()).await; + let res = inlet.unpause(&self.context, main_route.clone()); if let Some(err) = res.err() { error!("Error switching Inlet to the main route {}", err); } } _ => { - inlet.pause().await; + inlet.pause(); } } } if let Some(secure_channel) = self.additional_secure_channel.take() { - let res = self.context.stop_worker(secure_channel).await; + let res = self.context.stop_address(secure_channel.as_ref()); if let Some(err) = res.err() { error!("Error closing secure channel {}", err); @@ -423,7 +414,7 @@ impl AdditionalSessionReplacer for InletSessionReplacer { } if let Some(puncture) = self.udp_puncture.take() { - let res = puncture.stop(&self.context).await; + let res = puncture.stop(&self.context); if let Some(err) = res.err() { error!("Error stopping puncture {}", err); diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_outlets.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_outlets.rs index f3f56d44ed1..11383ae920d 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_outlets.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/tcp_outlets.rs @@ -68,11 +68,11 @@ impl NodeManagerWorker { } } - pub(super) async fn show_outlet( + pub(super) fn show_outlet( &self, worker_addr: &Address, ) -> Result, Response> { - match self.node_manager.show_outlet(worker_addr).await { + match self.node_manager.show_outlet(worker_addr) { Some(outlet) => Ok(Response::ok().body(outlet)), None => Err(Response::not_found_no_request(&format!( "Outlet with address {worker_addr} not found" @@ -80,10 +80,10 @@ impl NodeManagerWorker { } } - pub(super) async fn get_outlets(&self, req: &RequestHeader) -> Response> { + pub(super) fn get_outlets(&self, req: &RequestHeader) -> Response> { Response::ok() .with_headers(req) - .body(self.node_manager.list_outlets().await) + .body(self.node_manager.list_outlets()) } } @@ -101,11 +101,7 @@ impl NodeManager { access_control: OutletAccessControl, privileged: bool, ) -> Result { - let worker_addr = self - .registry - .outlets - .generate_worker_addr(worker_addr) - .await; + let worker_addr = self.registry.outlets.generate_worker_addr(worker_addr); info!( "Handling request to create outlet portal to {to} with worker {:?}", @@ -113,7 +109,7 @@ impl NodeManager { ); // Check registry for a duplicated key - if self.registry.outlets.contains_key(&worker_addr).await { + if self.registry.outlets.contains_key(&worker_addr) { let message = format!("A TCP outlet with address '{worker_addr}' already exists"); return Err(ockam_core::Error::new( Origin::Node, @@ -181,19 +177,15 @@ impl NodeManager { } else { self.tcp_transport .create_outlet(worker_addr.clone(), to.clone(), options) - .await }; Ok(match res { Ok(_) => { // TODO: Use better way to store outlets? - self.registry - .outlets - .insert( - worker_addr.clone(), - OutletInfo::new(to.clone(), Some(&worker_addr), privileged), - ) - .await; + self.registry.outlets.insert( + worker_addr.clone(), + OutletInfo::new(to.clone(), Some(&worker_addr), privileged), + ); self.cli_state .create_tcp_outlet(&self.node_name, &to, &worker_addr, &None, privileged) @@ -213,7 +205,7 @@ impl NodeManager { pub async fn delete_outlet(&self, worker_addr: &Address) -> Result> { info!(%worker_addr, "Handling request to delete outlet portal"); - if let Some(deleted_outlet) = self.registry.outlets.remove(worker_addr).await { + if let Some(deleted_outlet) = self.registry.outlets.remove(worker_addr) { debug!(%worker_addr, "Successfully removed outlet from node registry"); self.cli_state @@ -223,11 +215,7 @@ impl NodeManager { .delete_resource(&worker_addr.address().into()) .await?; - if let Err(e) = self - .tcp_transport - .stop_outlet(deleted_outlet.worker_addr.clone()) - .await - { + if let Err(e) = self.tcp_transport.stop_outlet(&deleted_outlet.worker_addr) { warn!(%worker_addr, %e, "Failed to stop outlet worker"); } trace!(%worker_addr, "Successfully stopped outlet"); @@ -238,9 +226,9 @@ impl NodeManager { } } - pub(super) async fn show_outlet(&self, worker_addr: &Address) -> Option { + pub(super) fn show_outlet(&self, worker_addr: &Address) -> Option { info!(%worker_addr, "Handling request to show outlet portal"); - if let Some(outlet_to_show) = self.registry.outlets.get(worker_addr).await { + if let Some(outlet_to_show) = self.registry.outlets.get(worker_addr) { debug!(%worker_addr, "Outlet not found in node registry"); Some(OutletStatus::new( outlet_to_show.to, diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/transport.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/transport.rs index d1976925510..e56b4b53d36 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/transport.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/transport.rs @@ -48,9 +48,9 @@ impl NodeManager { // Add all Hop workers as consumers for Demo purposes // Production nodes should not run any Hop workers - for hop in self.registry.hop_services.keys().await { + for hop in self.registry.hop_services.keys() { ctx.flow_controls() - .add_consumer(hop.clone(), &options.flow_control_id()); + .add_consumer(&hop, &options.flow_control_id()); } let connection = self.tcp_transport.connect(address, options).await?; @@ -63,7 +63,7 @@ impl NodeManager { Ok(listener.into()) } - async fn delete_tcp_connection(&self, address: String) -> Result<(), String> { + fn delete_tcp_connection(&self, address: String) -> Result<(), String> { let sender_address = match address.parse::() { Ok(socket_address) => self .tcp_transport() @@ -76,12 +76,11 @@ impl NodeManager { }; self.tcp_transport - .disconnect(sender_address.clone()) - .await + .disconnect(&sender_address) .map_err(|err| format!("Unable to disconnect from {sender_address}: {err}")) } - async fn delete_tcp_listener(&self, address: String) -> Result<(), String> { + fn delete_tcp_listener(&self, address: String) -> Result<(), String> { let listener_address = match address.parse::() { Ok(socket_address) => self .tcp_transport() @@ -95,7 +94,6 @@ impl NodeManager { self.tcp_transport .stop_listener(&listener_address) - .await .map_err(|err| format!("Unable to stop listener {listener_address}: {err}")) } } @@ -178,7 +176,7 @@ impl NodeManagerWorker { }) } - pub(super) async fn delete_tcp_connection( + pub(super) fn delete_tcp_connection( &self, delete: DeleteTransport, ) -> Result, Response> { @@ -186,12 +184,11 @@ impl NodeManagerWorker { self.node_manager .delete_tcp_connection(delete.address) - .await .map(|status| Response::ok().body(status)) .map_err(|msg| Response::bad_request_no_request(&msg)) } - pub(super) async fn delete_tcp_listener( + pub(super) fn delete_tcp_listener( &self, delete: DeleteTransport, ) -> Result, Response> { @@ -199,7 +196,6 @@ impl NodeManagerWorker { self.node_manager .delete_tcp_listener(delete.address) - .await .map(|status| Response::ok().body(status)) .map_err(|msg| Response::bad_request_no_request(&msg)) } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/worker.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/worker.rs index 2580e6bcd63..9570daac5d7 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/worker.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/worker.rs @@ -23,7 +23,7 @@ impl NodeManagerWorker { // TODO: This is never called. pub async fn stop(&self, ctx: &Context) -> Result<()> { self.node_manager.stop(ctx).await?; - ctx.stop_worker(NODEMANAGER_ADDR).await?; + ctx.stop_address(&NODEMANAGER_ADDR.into())?; Ok(()) } } @@ -69,7 +69,7 @@ impl NodeManagerWorker { encode_response(req, self.create_tcp_connection(ctx, dec.decode()?).await)? } (Delete, ["node", "tcp", "connection"]) => { - encode_response(req, self.delete_tcp_connection(dec.decode()?).await)? + encode_response(req, self.delete_tcp_connection(dec.decode()?))? } // ==*== Tcp Listeners ==*== @@ -81,48 +81,44 @@ impl NodeManagerWorker { encode_response(req, self.create_tcp_listener(dec.decode()?).await)? } (Delete, ["node", "tcp", "listener"]) => { - encode_response(req, self.delete_tcp_listener(dec.decode()?).await)? + encode_response(req, self.delete_tcp_listener(dec.decode()?))? } // ==*== Secure channels ==*== - (Get, ["node", "secure_channel"]) => { - encode_response(req, self.list_secure_channels().await)? - } + (Get, ["node", "secure_channel"]) => encode_response(req, self.list_secure_channels())?, (Get, ["node", "secure_channel_listener"]) => { - encode_response(req, self.list_secure_channel_listener().await)? + encode_response(req, self.list_secure_channel_listener())? } (Post, ["node", "secure_channel"]) => { encode_response(req, self.create_secure_channel(dec.decode()?, ctx).await)? } (Delete, ["node", "secure_channel"]) => { - encode_response(req, self.delete_secure_channel(dec.decode()?, ctx).await)? + encode_response(req, self.delete_secure_channel(dec.decode()?, ctx))? } (Get, ["node", "show_secure_channel"]) => { - encode_response(req, self.show_secure_channel(dec.decode()?).await)? + encode_response(req, self.show_secure_channel(dec.decode()?))? } (Post, ["node", "secure_channel_listener"]) => encode_response( req, self.create_secure_channel_listener(dec.decode()?, ctx) .await, )?, - (Delete, ["node", "secure_channel_listener"]) => encode_response( - req, - self.delete_secure_channel_listener(dec.decode()?, ctx) - .await, - )?, + (Delete, ["node", "secure_channel_listener"]) => { + encode_response(req, self.delete_secure_channel_listener(dec.decode()?, ctx))? + } (Get, ["node", "show_secure_channel_listener"]) => { - encode_response(req, self.show_secure_channel_listener(dec.decode()?).await)? + encode_response(req, self.show_secure_channel_listener(dec.decode()?))? } // ==*== Services ==*== (Post, ["node", "services", DefaultAddress::UPPERCASE_SERVICE]) => { - encode_response(req, self.start_uppercase_service(ctx, dec.decode()?).await)? + encode_response(req, self.start_uppercase_service(ctx, dec.decode()?))? } (Post, ["node", "services", DefaultAddress::ECHO_SERVICE]) => { encode_response(req, self.start_echoer_service(ctx, dec.decode()?).await)? } (Post, ["node", "services", DefaultAddress::HOP_SERVICE]) => { - encode_response(req, self.start_hop_service(ctx, dec.decode()?).await)? + encode_response(req, self.start_hop_service(ctx, dec.decode()?))? } (Post, ["node", "services", DefaultAddress::KAFKA_OUTLET]) => encode_response( req, @@ -149,12 +145,11 @@ impl NodeManagerWorker { )?, (Delete, ["node", "services", DefaultAddress::LEASE_MANAGER]) => encode_response( req, - self.delete_influxdb_lease_issuer_service(ctx, dec.decode()?) - .await, + self.delete_influxdb_lease_issuer_service(ctx, dec.decode()?), )?, - (Get, ["node", "services"]) => encode_response(req, self.list_services().await)?, + (Get, ["node", "services"]) => encode_response(req, self.list_services())?, (Get, ["node", "services", service_type]) => { - encode_response(req, self.list_services_of_type(service_type).await)? + encode_response(req, self.list_services_of_type(service_type))? } // ==*== Relay commands ==*== @@ -172,10 +167,10 @@ impl NodeManagerWorker { // ==*== Inlets & Outlets ==*== (Get, ["node", "inlet"]) => encode_response(req, self.get_inlets().await)?, (Get, ["node", "inlet", alias]) => encode_response(req, self.show_inlet(alias).await)?, - (Get, ["node", "outlet"]) => self.get_outlets(req).await.to_vec()?, + (Get, ["node", "outlet"]) => self.get_outlets(req).to_vec()?, (Get, ["node", "outlet", addr]) => { let addr: Address = addr.to_string().into(); - encode_response(req, self.show_outlet(&addr).await)? + encode_response(req, self.show_outlet(&addr))? } (Post, ["node", "inlet"]) => { encode_response(req, self.create_inlet(ctx, dec.decode()?).await)? diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/workers.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/workers.rs index 8a350ed4141..bf8bc00145b 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/workers.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/workers.rs @@ -11,7 +11,7 @@ impl NodeManagerWorker { ctx: &Context, ) -> Result, Response> { let list = ctx - .list_workers() + .list_workers()? .into_iter() .map(|addr| WorkerStatus::new(addr.address())) .collect(); diff --git a/implementations/rust/ockam/ockam_api/src/rendezvous_healthcheck.rs b/implementations/rust/ockam/ockam_api/src/rendezvous_healthcheck.rs index 182395dce07..1f696e0baad 100644 --- a/implementations/rust/ockam/ockam_api/src/rendezvous_healthcheck.rs +++ b/implementations/rust/ockam/ockam_api/src/rendezvous_healthcheck.rs @@ -2,7 +2,7 @@ use crate::DefaultAddress; use ockam::transport::HostnamePort; use ockam::udp::{RendezvousClient, UdpBindArguments, UdpBindOptions, UdpTransport}; use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{route, AsyncTryClone, Error, Result}; +use ockam_core::{route, Error, Result, TryClone}; use ockam_node::Context; use std::net::SocketAddr; use tokio::io::{AsyncReadExt, AsyncWriteExt}; @@ -17,7 +17,7 @@ pub struct RendezvousHealthcheck { } impl RendezvousHealthcheck { - pub async fn create( + pub fn create( healthcheck_listening_address: &str, udp: &UdpTransport, udp_socket_address: SocketAddr, @@ -28,7 +28,7 @@ impl RendezvousHealthcheck { udp_socket_address.to_string() }; - let ctx = udp.ctx().async_try_clone().await?; + let ctx = udp.ctx().try_clone()?; let task = RendezvousHealthcheckTask { ctx, @@ -147,7 +147,7 @@ impl RendezvousHealthcheckTask { ) }); - self.udp.unbind(bind).await?; + self.udp.unbind(bind.as_ref())?; res } diff --git a/implementations/rust/ockam/ockam_api/src/session/session.rs b/implementations/rust/ockam/ockam_api/src/session/session.rs index 0beebe7f158..3532b0c280c 100644 --- a/implementations/rust/ockam/ockam_api/src/session/session.rs +++ b/implementations/rust/ockam/ockam_api/src/session/session.rs @@ -148,7 +148,7 @@ impl Session { } /// Create a Session - pub async fn create( + pub fn create( ctx: &Context, replacer: Arc>, additional_session_options: Option, @@ -160,20 +160,17 @@ impl Session { RETRY_DELAY, PING_INTERVAL, ) - .await } /// Create a Session - pub async fn create_extended( + pub fn create_extended( ctx: &Context, replacer: Arc>, additional_session_options: Option, retry_delay: Duration, ping_interval: Duration, ) -> Result { - let ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; Ok(Self::new( ctx, @@ -278,7 +275,7 @@ impl Session { } /// Start monitoring the session - pub async fn start_monitoring(&mut self) -> Result<()> { + pub fn start_monitoring(&mut self) -> Result<()> { let (ping_channel_sender, ping_channel_receiver) = mpsc::channel(1); // Will shut down itself when we stop the Collector @@ -291,17 +288,13 @@ impl Session { WorkerBuilder::new(Collector::new(ping_channel_sender)) .with_address(self.collector_address.clone()) .with_outgoing_access_control(DenyAll) - .start(&self.ctx) - .await?; + .start(&self.ctx)?; - let ctx = self - .ctx - .new_detached( - Address::random_tagged("Session.ctx.run_loop"), - DenyAll, - AllowAll, - ) - .await?; + let ctx = self.ctx.new_detached( + Address::random_tagged("Session.ctx.run_loop"), + DenyAll, + AllowAll, + )?; let handle = tokio::spawn(Self::run_loop( ctx, @@ -328,17 +321,13 @@ impl Session { WorkerBuilder::new(Collector::new(ping_channel_sender)) .with_address(additional_state.collector_address.clone()) .with_outgoing_access_control(DenyAll) - .start(&self.ctx) - .await?; - - let ctx = self - .ctx - .new_detached( - Address::random_tagged("Session.ctx.run_loop.additional"), - DenyAll, - AllowAll, - ) - .await?; + .start(&self.ctx)?; + + let ctx = self.ctx.new_detached( + Address::random_tagged("Session.ctx.run_loop.additional"), + DenyAll, + AllowAll, + )?; let handle = tokio::spawn(Self::run_loop_additional( ctx, @@ -375,10 +364,7 @@ impl Session { .await; additional_state.shared_state.status.set_down(); - _ = self - .ctx - .stop_worker(additional_state.collector_address) - .await; + _ = self.ctx.stop_address(&additional_state.collector_address); } } @@ -393,7 +379,7 @@ impl Session { // ping_receiver_handle task will shut down itself when Collector Worker drops the sender - _ = self.ctx.stop_worker(self.collector_address.clone()).await; + _ = self.ctx.stop_address(&self.collector_address); } /// Stop everything @@ -414,7 +400,7 @@ impl Session { pings.push(ping); let ping_encoded = Encodable::encode(ping)?; - let echo_route = route![ping_route.clone(), DefaultAddress::ECHO_SERVICE]; + let echo_route = ping_route.clone() + DefaultAddress::ECHO_SERVICE; trace! { key = %key, addr = %ping_route, @@ -433,7 +419,7 @@ impl Session { .map(|x| x.flow_control_id().clone()) { ctx.flow_controls() - .add_consumer(collector_address.clone(), &flow_control_id); + .add_consumer(&collector_address, &flow_control_id); } let local_message = LocalMessage::new() diff --git a/implementations/rust/ockam/ockam_api/src/test_utils/mod.rs b/implementations/rust/ockam/ockam_api/src/test_utils/mod.rs index e2ec9d23c72..aa1a99de1a0 100644 --- a/implementations/rust/ockam/ockam_api/src/test_utils/mod.rs +++ b/implementations/rust/ockam/ockam_api/src/test_utils/mod.rs @@ -2,7 +2,7 @@ use crate::config::lookup::InternetAddress; use crate::nodes::service::{NodeManagerCredentialRetrieverOptions, NodeManagerTrustOptions}; -use ockam_node::{Context, NodeBuilder}; +use ockam_node::{Context, Executor, NodeBuilder}; use sqlx::__rt::timeout; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::ops::Deref; @@ -20,7 +20,7 @@ use ockam::identity::SecureChannels; use ockam::tcp::{TcpListenerOptions, TcpTransport}; use ockam::transport::HostnamePort; use ockam::Result; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_node::database::{DatabaseConfiguration, SqlxDatabase}; use crate::authenticator::credential_issuer::{DEFAULT_CREDENTIAL_VALIDITY, PROJECT_MEMBER_SCHEMA}; @@ -58,7 +58,7 @@ pub async fn start_manager_for_tests( bind_addr: Option<&str>, trust_options: Option, ) -> Result { - let tcp = TcpTransport::create(context).await?; + let tcp = TcpTransport::create(context)?; let tcp_listener = tcp .listen( bind_addr.unwrap_or("127.0.0.1:0"), @@ -98,7 +98,7 @@ pub async fn start_manager_for_tests( NodeManagerGeneralOptions::new(cli_state.clone(), node_name, true, None, false), NodeManagerTransportOptions::new( tcp_listener.flow_control_id().clone(), - tcp.async_try_clone().await?, + tcp.try_clone()?, None, ), trust_options.unwrap_or_else(|| { @@ -115,15 +115,13 @@ pub async fn start_manager_for_tests( let node_manager = Arc::new(node_manager); let node_manager_worker = NodeManagerWorker::new(node_manager.clone()); - context - .start_worker(NODEMANAGER_ADDR, node_manager_worker) - .await?; + context.start_worker(NODEMANAGER_ADDR, node_manager_worker)?; let secure_channels = node_manager.secure_channels(); let handle = NodeManagerHandle { cli_state, node_manager, - tcp: tcp.async_try_clone().await?, + tcp: tcp.try_clone()?, secure_channels, }; @@ -200,6 +198,7 @@ pub async fn start_tcp_echo_server() -> EchoServerHandle { } pub struct TestNode { + pub executor: Executor, pub context: Context, pub node_manager_handle: NodeManagerHandle, } @@ -209,16 +208,14 @@ impl TestNode { /// needs be cleaned-up before a test is executed pub async fn clean() -> Result<()> { if let Some(configuration) = DatabaseConfiguration::postgres()? { - let db = SqlxDatabase::create_no_migration(&configuration) - .await - .unwrap(); + let db = SqlxDatabase::create_no_migration(&configuration).await?; db.drop_all_postgres_tables().await?; }; Ok(()) } pub async fn create(runtime: Arc, listen_addr: Option<&str>) -> Self { - let (mut context, _executor) = NodeBuilder::new().with_runtime(runtime.clone()).build(); + let (mut context, executor) = NodeBuilder::new().with_runtime(runtime).build(); let node_manager_handle = start_manager_for_tests( &mut context, listen_addr, @@ -233,6 +230,7 @@ impl TestNode { .expect("cannot start node manager"); Self { + executor, context, node_manager_handle, } diff --git a/implementations/rust/ockam/ockam_api/tests/authority.rs b/implementations/rust/ockam/ockam_api/tests/authority.rs index 7ec768ffc0f..094d42862cc 100644 --- a/implementations/rust/ockam/ockam_api/tests/authority.rs +++ b/implementations/rust/ockam/ockam_api/tests/authority.rs @@ -10,7 +10,7 @@ async fn authority_starts_with_default_configuration(ctx: &mut Context) -> Resul let configuration = default_configuration().await?; start_authority_node(ctx, &configuration).await?; - let workers = ctx.list_workers(); + let workers = ctx.list_workers()?; assert!(!workers.contains(&Address::from(DefaultAddress::DIRECT_AUTHENTICATOR))); assert!(!workers.contains(&Address::from(DefaultAddress::ENROLLMENT_TOKEN_ACCEPTOR))); @@ -28,7 +28,7 @@ async fn authority_starts_direct_authenticator(ctx: &mut Context) -> Result<()> configuration.no_direct_authentication = false; start_authority_node(ctx, &configuration).await?; - let workers = ctx.list_workers(); + let workers = ctx.list_workers()?; assert!(workers.contains(&Address::from(DefaultAddress::DIRECT_AUTHENTICATOR))); assert!(!workers.contains(&Address::from(DefaultAddress::ENROLLMENT_TOKEN_ACCEPTOR))); @@ -46,7 +46,7 @@ async fn authority_starts_enrollment_token(ctx: &mut Context) -> Result<()> { configuration.no_token_enrollment = false; start_authority_node(ctx, &configuration).await?; - let workers = ctx.list_workers(); + let workers = ctx.list_workers()?; assert!(!workers.contains(&Address::from(DefaultAddress::DIRECT_AUTHENTICATOR))); assert!(workers.contains(&Address::from(DefaultAddress::ENROLLMENT_TOKEN_ACCEPTOR))); diff --git a/implementations/rust/ockam/ockam_api/tests/common/common.rs b/implementations/rust/ockam/ockam_api/tests/common/common.rs index b1a1a381488..ed5dff4c314 100644 --- a/implementations/rust/ockam/ockam_api/tests/common/common.rs +++ b/implementations/rust/ockam/ockam_api/tests/common/common.rs @@ -115,7 +115,7 @@ pub async fn start_authority( .await?; let authority_node_client = NodeManager::authority_node_client( - &TcpTransport::create(ctx).await?, + &TcpTransport::create(ctx)?, secure_channels.clone(), &configuration.identifier, &MultiAddr::try_from("/secure/api")?, diff --git a/implementations/rust/ockam/ockam_api/tests/common/mod.rs b/implementations/rust/ockam/ockam_api/tests/common/mod.rs index 9a3370c152a..eae79b75ff0 100644 --- a/implementations/rust/ockam/ockam_api/tests/common/mod.rs +++ b/implementations/rust/ockam/ockam_api/tests/common/mod.rs @@ -4,5 +4,3 @@ pub mod common; pub mod session; #[allow(dead_code)] pub mod test_spans; -#[allow(dead_code)] -pub mod trace_code; diff --git a/implementations/rust/ockam/ockam_api/tests/common/session.rs b/implementations/rust/ockam/ockam_api/tests/common/session.rs index 86e2723d5be..285da5285ea 100644 --- a/implementations/rust/ockam/ockam_api/tests/common/session.rs +++ b/implementations/rust/ockam/ockam_api/tests/common/session.rs @@ -81,11 +81,11 @@ impl Worker for MockHop { async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { if !self.responsive.load(Ordering::Relaxed) { - info!("Drop Hop message, {}", ctx.address()); + info!("Drop Hop message, {}", ctx.primary_address()); return Ok(()); } - info!("Forward Hop message {}", ctx.address()); + info!("Forward Hop message {}", ctx.primary_address()); let msg = msg.into_local_message(); let msg = msg.pop_front_onward_route()?; diff --git a/implementations/rust/ockam/ockam_api/tests/common/trace_code.rs b/implementations/rust/ockam/ockam_api/tests/common/trace_code.rs deleted file mode 100644 index 148dbac9cd7..00000000000 --- a/implementations/rust/ockam/ockam_api/tests/common/trace_code.rs +++ /dev/null @@ -1,73 +0,0 @@ -use crate::common::test_spans::Trace; -use ockam_api::logs::{ExportingConfiguration, LoggingConfiguration, LoggingTracing}; -use ockam_core::{AsyncTryClone, OpenTelemetryContext}; -use ockam_node::{Context, NodeBuilder}; -use opentelemetry::global; -use opentelemetry::trace::{FutureExt, Tracer}; -use opentelemetry_sdk::export::trace::SpanData; -use opentelemetry_sdk::testing::logs::InMemoryLogsExporter; -use opentelemetry_sdk::testing::trace::InMemorySpanExporter; -use std::future::Future; - -/// Run an async function using a tracer and return: -/// -/// - the return value of the function -/// - all the exported spans -pub fn trace_code(f: impl Fn(Context) -> F + Send + Sync + 'static) -> (F::Output, Vec) -where - F: Future + Send + 'static, - F::Output: Send + 'static, -{ - let spans_exporter = InMemorySpanExporter::default(); - let guard = LoggingTracing::setup_with_exporters( - spans_exporter.clone(), - InMemoryLogsExporter::default(), - &LoggingConfiguration::off() - .unwrap() - .set_all_crates() - .set_log_level(tracing_core::metadata::Level::TRACE), - &ExportingConfiguration::foreground().unwrap(), - "test", - None, - ); - - let (mut ctx, mut executor) = NodeBuilder::new().build(); - - let tracer = global::tracer("ockam-test"); - let result = executor - .execute_no_abort(async move { - let result = tracer - .in_span("root", |_| { - ctx.set_tracing_context(OpenTelemetryContext::current()); - async { f(ctx.async_try_clone().await.unwrap()).await }.with_current_context() - }) - .await; - let _ = ctx.stop().await; - result - }) - .unwrap(); - - // get the exported spans - guard.force_flush(); - let spans = spans_exporter.get_finished_spans().unwrap(); - (result, spans) -} - -/// Return a string displaying the traces for all the given spans -pub fn display_traces(spans: Vec) -> String { - let mut traces = Trace::from_span_data(spans); - traces.sort_by_key(|t| t.to_string()); - - // remove some uninteresting traces based on their root name - traces.retain(|t| { - !["start", "shutdown", "initialize", "process"] - .iter() - .any(|v| t.0.to_string().split('\n').collect::>()[0].ends_with(v)) - }); - - traces - .iter() - .map(|t| t.to_string()) - .collect::>() - .join("\n") -} diff --git a/implementations/rust/ockam/ockam_api/tests/credential_issuer.rs b/implementations/rust/ockam/ockam_api/tests/credential_issuer.rs index ec1bd9eef36..5f265209d36 100644 --- a/implementations/rust/ockam/ockam_api/tests/credential_issuer.rs +++ b/implementations/rust/ockam/ockam_api/tests/credential_issuer.rs @@ -64,11 +64,14 @@ async fn credential(ctx: &mut Context) -> Result<()> { // Create the CredentialIssuer: let options = SecureChannelListenerOptions::new(); let sc_flow_control_id = options.spawner_flow_control_id(); - secure_channels - .create_secure_channel_listener(ctx, &auth_identifier, api_worker_addr.clone(), options) - .await?; + secure_channels.create_secure_channel_listener( + ctx, + &auth_identifier, + api_worker_addr.clone(), + options, + )?; ctx.flow_controls() - .add_consumer(auth_worker_addr.clone(), &sc_flow_control_id); + .add_consumer(&auth_worker_addr, &sc_flow_control_id); let auth = CredentialIssuerWorker::new( members, identities.identities_attributes(), @@ -79,7 +82,7 @@ async fn credential(ctx: &mut Context) -> Result<()> { None, true, ); - ctx.start_worker(auth_worker_addr.clone(), auth).await?; + ctx.start_worker(auth_worker_addr.clone(), auth)?; // Connect to the API channel from the member: let e2a = secure_channels diff --git a/implementations/rust/ockam/ockam_api/tests/latency.rs b/implementations/rust/ockam/ockam_api/tests/latency.rs index 4eb7bf974ee..9d89d34e2de 100644 --- a/implementations/rust/ockam/ockam_api/tests/latency.rs +++ b/implementations/rust/ockam/ockam_api/tests/latency.rs @@ -64,7 +64,7 @@ pub fn measure_message_latency_two_nodes() { first_node .context .flow_controls() - .add_consumer(first_node.context.address(), &flow_control_id); + .add_consumer(first_node.context.primary_address(), &flow_control_id); } let payload = NeutralMessage::from(vec![1, 2, 3, 4]); @@ -102,8 +102,8 @@ pub fn measure_message_latency_two_nodes() { elapsed.div_f32(10_000f32) ); - first_node.context.stop().await?; - second_node.context.stop().await?; + first_node.context.shutdown_node().await?; + second_node.context.shutdown_node().await?; Ok(()) }; @@ -194,8 +194,8 @@ pub fn measure_buffer_latency_two_nodes_portal() { elapsed.div_f32(10_000f32) ); - first_node.context.stop().await?; - second_node.context.stop().await?; + first_node.context.shutdown_node().await?; + second_node.context.shutdown_node().await?; Ok(()) }; diff --git a/implementations/rust/ockam/ockam_api/tests/portals.rs b/implementations/rust/ockam/ockam_api/tests/portals.rs index b86a303bfc8..1165d1886cd 100644 --- a/implementations/rust/ockam/ockam_api/tests/portals.rs +++ b/implementations/rust/ockam/ockam_api/tests/portals.rs @@ -151,7 +151,7 @@ fn portal_node_goes_down_reconnect() { socket.read_exact(&mut buf).await.unwrap(); assert_eq!(&buf, b"hello"); - second_node.context.stop().await?; + second_node.context.shutdown_node().await?; // now let's verify the inlet has been detected as down loop { @@ -206,8 +206,8 @@ fn portal_node_goes_down_reconnect() { socket.read_exact(&mut buf).await.unwrap(); assert_eq!(&buf, b"hello"); - third_node.context.stop().await?; - first_node.context.stop().await?; + third_node.context.shutdown_node().await?; + first_node.context.shutdown_node().await?; Ok(()) }; @@ -340,8 +340,8 @@ fn portal_low_bandwidth_connection_keep_working_for_60s() { tokio::time::sleep(Duration::from_millis(1000)).await; } - second_node.context.stop().await?; - first_node.context.stop().await?; + second_node.context.shutdown_node().await?; + first_node.context.shutdown_node().await?; Ok(()) }; @@ -451,8 +451,8 @@ fn portal_heavy_load_exchanged() { assert!(payload == incoming_buffer); let _ = join_tx.await.unwrap(); - second_node.context.stop().await?; - first_node.context.stop().await?; + second_node.context.shutdown_node().await?; + first_node.context.shutdown_node().await?; Ok(()) }; @@ -603,8 +603,8 @@ fn test_portal_payload_transfer(outgoing_disruption: Disruption, incoming_disrup // using assert to avoid MB of data being shown in the logs assert!(random_buffer[0..size] == incoming_buffer[0..size]); - second_node.context.stop().await?; - first_node.context.stop().await?; + second_node.context.shutdown_node().await?; + first_node.context.shutdown_node().await?; Ok(()) }; diff --git a/implementations/rust/ockam/ockam_api/tests/session.rs b/implementations/rust/ockam/ockam_api/tests/session.rs index 1fbb2d0f3d8..1e319c90e14 100644 --- a/implementations/rust/ockam/ockam_api/tests/session.rs +++ b/implementations/rust/ockam/ockam_api/tests/session.rs @@ -17,9 +17,7 @@ async fn connect__unavailable__should_fail(ctx: &mut Context) -> Result<()> { MockReplacer::default(), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -45,8 +43,7 @@ async fn connect__unavailable__should_fail(ctx: &mut Context) -> Result<()> { .load(Ordering::Relaxed)); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; mock_replacer .lock() @@ -67,9 +64,7 @@ async fn connect__available__should_succeed(ctx: &mut Context) -> Result<()> { MockReplacer::default(), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -81,8 +76,7 @@ async fn connect__available__should_succeed(ctx: &mut Context) -> Result<()> { ); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; let res = session.initial_connect().await; assert!(res.is_ok()); @@ -97,9 +91,7 @@ async fn start_monitoring__available__should_be_up_fast(ctx: &mut Context) -> Re MockReplacer::default(), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -111,15 +103,14 @@ async fn start_monitoring__available__should_be_up_fast(ctx: &mut Context) -> Re ); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; - assert!(!ctx.is_worker_registered_at(session.collector_address())); + assert!(!ctx.is_worker_registered_at(session.collector_address())?); // Start the Session in a separate task - session.start_monitoring().await?; + session.start_monitoring()?; - assert!(ctx.is_worker_registered_at(session.collector_address())); + assert!(ctx.is_worker_registered_at(session.collector_address())?); let mut time_to_restore = 0; @@ -166,9 +157,7 @@ async fn start_monitoring__temporary_unavailable__should_eventually_be_up( MockReplacer::default(), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -180,8 +169,7 @@ async fn start_monitoring__temporary_unavailable__should_eventually_be_up( ); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; mock_replacer .lock() @@ -190,7 +178,7 @@ async fn start_monitoring__temporary_unavailable__should_eventually_be_up( .store(false, Ordering::Relaxed); // Start the Session in a separate task - session.start_monitoring().await?; + session.start_monitoring()?; ctx.sleep(Duration::from_millis(250)).await; @@ -242,9 +230,7 @@ async fn start_monitoring__go_down__should_notice(ctx: &mut Context) -> Result<( MockReplacer::default(), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -258,13 +244,12 @@ async fn start_monitoring__go_down__should_notice(ctx: &mut Context) -> Result<( // Session relies on echo to verify if a session is alive let echoer = MockEchoer::new(); let echoer_responsive = echoer.responsive.clone(); - ctx.start_worker(Address::from_string("echo"), echoer) - .await?; + ctx.start_worker(Address::from_string("echo"), echoer)?; session.initial_connect().await?; // Start the Session in a separate task - session.start_monitoring().await?; + session.start_monitoring()?; ctx.sleep(Duration::from_secs(5)).await; @@ -309,9 +294,7 @@ async fn start_monitoring__packet_lost__should_be_up(ctx: &mut Context) -> Resul MockReplacer::default(), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -325,15 +308,14 @@ async fn start_monitoring__packet_lost__should_be_up(ctx: &mut Context) -> Resul // Session relies on echo to verify if a session is alive let echoer = MockEchoer::new(); let echoer_drop_every = echoer.drop_every.clone(); - ctx.start_worker(Address::from_string("echo"), echoer) - .await?; + ctx.start_worker(Address::from_string("echo"), echoer)?; echoer_drop_every.store(2, Ordering::Relaxed); session.initial_connect().await?; // Start the Session in a separate task - session.start_monitoring().await?; + session.start_monitoring()?; for _ in 0..100 { assert!(session.last_outcome().is_some()); @@ -358,9 +340,7 @@ async fn start_monitoring__unstable_connection__should_be_resilient( MockReplacer::default(), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -374,13 +354,12 @@ async fn start_monitoring__unstable_connection__should_be_resilient( // Session relies on echo to verify if a session is alive let echoer = MockEchoer::new(); let echoer_responsive = echoer.responsive.clone(); - ctx.start_worker(Address::from_string("echo"), echoer) - .await?; + ctx.start_worker(Address::from_string("echo"), echoer)?; session.initial_connect().await?; // Start the Session in a separate task - session.start_monitoring().await?; + session.start_monitoring()?; for _ in 0..5 { echoer_responsive.store(false, Ordering::Relaxed); diff --git a/implementations/rust/ockam/ockam_api/tests/session_additional.rs b/implementations/rust/ockam/ockam_api/tests/session_additional.rs index 8a52cf4fb1c..fa88a4c1cb4 100644 --- a/implementations/rust/ockam/ockam_api/tests/session_additional.rs +++ b/implementations/rust/ockam/ockam_api/tests/session_additional.rs @@ -20,9 +20,7 @@ async fn connect__unavailable__should_fail(ctx: &mut Context) -> Result<()> { MockReplacer::new("additional", route![]), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -64,8 +62,7 @@ async fn connect__unavailable__should_fail(ctx: &mut Context) -> Result<()> { .load(Ordering::Relaxed)); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; mock_replacer .lock() @@ -100,9 +97,7 @@ async fn connect__only_main_available_no_fallback__should_fail(ctx: &mut Context MockReplacer::new("additional", route![]), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -119,8 +114,7 @@ async fn connect__only_main_available_no_fallback__should_fail(ctx: &mut Context ); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; additional_mock_replacer .lock() @@ -155,9 +149,7 @@ async fn connect__only_main_available_fallback__should_succeed(ctx: &mut Context MockReplacer::new("additional", route![]), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -174,8 +166,7 @@ async fn connect__only_main_available_fallback__should_succeed(ctx: &mut Context ); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; additional_mock_replacer .lock() @@ -192,7 +183,7 @@ async fn connect__only_main_available_fallback__should_succeed(ctx: &mut Context .create_called .load(Ordering::Relaxed)); - session.start_monitoring().await?; + session.start_monitoring()?; sleep(Duration::from_millis(250)).await; @@ -229,9 +220,7 @@ async fn start_monitoring__available__should_succeed(ctx: &mut Context) -> Resul MockReplacer::new("additional", route![]), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -248,10 +237,9 @@ async fn start_monitoring__available__should_succeed(ctx: &mut Context) -> Resul ); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; - session.start_monitoring().await?; + session.start_monitoring()?; sleep(Duration::from_millis(250)).await; @@ -292,7 +280,7 @@ async fn start_monitoring__additional_is_down__should_recreate(ctx: &mut Context let hop = MockHop::new(); let hop_responsive = hop.responsive.clone(); - ctx.start_worker("hop", hop).await?; + ctx.start_worker("hop", hop)?; let mock_replacer = Arc::new(ockam_node::compat::asynchronous::Mutex::new( MockReplacer::new("main", route![]), @@ -301,9 +289,7 @@ async fn start_monitoring__additional_is_down__should_recreate(ctx: &mut Context MockReplacer::new("additional", route!["hop"]), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -320,12 +306,11 @@ async fn start_monitoring__additional_is_down__should_recreate(ctx: &mut Context ); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; session.initial_connect().await?; - session.start_monitoring().await?; + session.start_monitoring()?; additional_mock_replacer .lock() @@ -382,12 +367,12 @@ async fn start_monitoring__both_down__should_recreate(ctx: &mut Context) -> Resu let hop_main = MockHop::new(); let hop_main_responsive = hop_main.responsive.clone(); - ctx.start_worker("hop_main", hop_main).await?; + ctx.start_worker("hop_main", hop_main)?; let hop_additional = MockHop::new(); let hop_additional_responsive = hop_additional.responsive.clone(); - ctx.start_worker("hop_additional", hop_additional).await?; + ctx.start_worker("hop_additional", hop_additional)?; let mock_replacer = Arc::new(ockam_node::compat::asynchronous::Mutex::new( MockReplacer::new("main", route!["hop_main"]), @@ -396,9 +381,7 @@ async fn start_monitoring__both_down__should_recreate(ctx: &mut Context) -> Resu MockReplacer::new("additional", route!["hop_additional"]), )); - let session_ctx = ctx - .new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll) - .await?; + let session_ctx = ctx.new_detached(Address::random_tagged("Session.ctx"), DenyAll, AllowAll)?; // Create a new Session instance let mut session = Session::new( @@ -415,8 +398,7 @@ async fn start_monitoring__both_down__should_recreate(ctx: &mut Context) -> Resu ); // Session relies on echo to verify if a session is alive - ctx.start_worker(Address::from_string("echo"), MockEchoer::new()) - .await?; + ctx.start_worker(Address::from_string("echo"), MockEchoer::new())?; session.initial_connect().await?; @@ -429,7 +411,7 @@ async fn start_monitoring__both_down__should_recreate(ctx: &mut Context) -> Resu hop_main_responsive.store(false, Ordering::Relaxed); hop_additional_responsive.store(false, Ordering::Relaxed); - session.start_monitoring().await?; + session.start_monitoring()?; sleep(Duration::from_millis(4500)).await; diff --git a/implementations/rust/ockam/ockam_app_lib/src/incoming_services/state.rs b/implementations/rust/ockam/ockam_app_lib/src/incoming_services/state.rs index 0a4b62a8e2d..dc8b84808b5 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/incoming_services/state.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/incoming_services/state.rs @@ -454,6 +454,6 @@ mod tests { assert_eq!("custom_user_name", service.name()); assert_eq!("/project/project_id/service/forward_to_I12ab34cd56ef12ab34cd56ef12ab34cd56ef12aba1b2c3d4e5f6a6b5c4d3e2f1/secure/api/service/remote_service_name", service.service_route(None)); - context.stop().await + context.shutdown_node().await } } diff --git a/implementations/rust/ockam/ockam_app_lib/src/invitations/commands.rs b/implementations/rust/ockam/ockam_app_lib/src/invitations/commands.rs index 8fb2c049cfa..4e618287dba 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/invitations/commands.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/invitations/commands.rs @@ -192,7 +192,7 @@ impl AppState { outlet_worker_addr: &Address, ) -> Result<(), String> { let node_manager = self.node_manager().await; - let outlets = node_manager.list_outlets().await; + let outlets = node_manager.list_outlets(); let to = outlets .into_iter() diff --git a/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/create.rs b/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/create.rs index e656b3bc85a..7a169d3bcdc 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/create.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/create.rs @@ -33,7 +33,7 @@ impl AppState { .await?; let incoming_ac = ac.create_incoming(); - let outgoing_ac = ac.create_outgoing(self.context_ref()).await?; + let outgoing_ac = ac.create_outgoing(self.context_ref())?; match node_manager .create_outlet( &self.context(), diff --git a/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/invitation_access_control.rs b/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/invitation_access_control.rs index d33d81c5c31..96a5f1c6a40 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/invitation_access_control.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/invitation_access_control.rs @@ -93,17 +93,15 @@ impl InvitationAccessControl { } } - pub async fn create_outgoing( + pub fn create_outgoing( &self, ctx: &Context, ) -> ockam_core::Result { - let ctx = ctx - .new_detached( - Address::random_tagged("InvitationOutgoingAccessControl"), - DenyAll, - DenyAll, - ) - .await?; + let ctx = ctx.new_detached( + Address::random_tagged("InvitationOutgoingAccessControl"), + DenyAll, + DenyAll, + )?; Ok(InvitationOutgoingAccessControl { ctx, @@ -190,7 +188,7 @@ pub struct InvitationOutgoingAccessControl { #[async_trait] impl OutgoingAccessControl for InvitationOutgoingAccessControl { async fn is_authorized(&self, relay_message: &RelayMessage) -> ockam_core::Result { - let identifier = match Abac::get_outgoing_identifier(&self.ctx, relay_message).await? { + let identifier = match Abac::get_outgoing_identifier(&self.ctx, relay_message)? { Some(identifier) => identifier, None => { debug!("identity identifier not found; access denied"); diff --git a/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/state.rs b/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/state.rs index fdcaba7ff96..e092e0e6dbb 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/state.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/shared_service/tcp_outlet/state.rs @@ -52,7 +52,7 @@ impl AppState { }; let incoming_ac = access_control.create_incoming(); - let outgoing_ac = match access_control.create_outgoing(self.context_ref()).await { + let outgoing_ac = match access_control.create_outgoing(self.context_ref()) { Ok(a) => a, Err(e) => { error!( diff --git a/implementations/rust/ockam/ockam_app_lib/src/state/mod.rs b/implementations/rust/ockam/ockam_app_lib/src/state/mod.rs index b1c89ddb383..52b539aec07 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/state/mod.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/state/mod.rs @@ -8,9 +8,9 @@ use tracing::{error, info, trace, warn}; pub use kind::StateKind; use ockam::tcp::{TcpListenerOptions, TcpTransport}; -use ockam::AsyncTryClone; use ockam::Context; use ockam::NodeBuilder; +use ockam::TryClone; use ockam_api::cli_state::CliState; use ockam_api::cloud::enroll::auth0::UserInfo; use ockam_api::cloud::project::Project; @@ -122,7 +122,7 @@ impl AppState { #[cfg(test)] pub async fn test(context: &Context, cli_state: CliState) -> AppState { Self::make( - Arc::new(context.async_try_clone().await.unwrap()), + Arc::new(context.try_clone().unwrap()), None, None, cli_state, @@ -319,8 +319,8 @@ impl AppState { info!("stopped the old node manager"); - for w in self.context.list_workers() { - let _ = self.context.stop_worker(w.address()).await; + for w in self.context.list_workers()? { + let _ = self.context.stop_address(&w.address().into()); } info!("stopped all the ctx workers"); @@ -388,13 +388,7 @@ impl AppState { } pub async fn background_node(&self, node_name: &str) -> Result { - let tcp = self - .node_manager - .read() - .await - .tcp_transport() - .async_try_clone() - .await?; + let tcp = self.node_manager.read().await.tcp_transport().try_clone()?; Ok( BackgroundNodeClient::create_to_node_with_tcp(&tcp, &self.state().await, node_name) .await?, @@ -419,7 +413,7 @@ impl AppState { /// Return the list of currently running outlets pub async fn tcp_outlet_list(&self) -> Vec { let node_manager = self.node_manager.read().await; - node_manager.list_outlets().await + node_manager.list_outlets() } pub async fn user_info(&self) -> Result { @@ -691,7 +685,7 @@ pub(crate) async fn make_node_manager( ctx: Arc, cli_state: &CliState, ) -> miette::Result> { - let tcp = TcpTransport::create(&ctx).await.into_diagnostic()?; + let tcp = TcpTransport::create(&ctx).into_diagnostic()?; let options = TcpListenerOptions::new(); let listener = tcp .listen(&"127.0.0.1:0", options) @@ -726,11 +720,10 @@ pub(crate) async fn make_node_manager( let node_manager_worker = NodeManagerWorker::new(node_manager.clone()); ctx.start_worker(NODEMANAGER_ADDR, node_manager_worker) - .await .into_diagnostic()?; ctx.flow_controls() - .add_consumer(NODEMANAGER_ADDR, listener.flow_control_id()); + .add_consumer(&NODEMANAGER_ADDR.into(), listener.flow_control_id()); Ok(node_manager) } diff --git a/implementations/rust/ockam/ockam_command/src/identity/delete.rs b/implementations/rust/ockam/ockam_command/src/identity/delete.rs index b89afffa037..9760e318cfd 100644 --- a/implementations/rust/ockam/ockam_command/src/identity/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/identity/delete.rs @@ -8,7 +8,6 @@ use console::Term; use ockam_api::colors::color_primary; use ockam_api::fmt_ok; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_core::AsyncTryClone; const LONG_ABOUT: &str = include_str!("./static/delete/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); @@ -47,7 +46,7 @@ impl DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(Clone)] pub struct DeleteTui { opts: CommandGlobalOpts, cmd: DeleteCommand, diff --git a/implementations/rust/ockam/ockam_command/src/kafka/inlet/delete.rs b/implementations/rust/ockam/ockam_command/src/kafka/inlet/delete.rs index 0eb4a53cca7..8d21fb43a5b 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/inlet/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/inlet/delete.rs @@ -9,7 +9,7 @@ use ockam_api::nodes::models::services::{DeleteServiceRequest, ServiceStatus}; use ockam_api::nodes::BackgroundNodeClient; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_core::api::Request; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_node::Context; use crate::tui::{DeleteCommandTui, PluralTerm}; @@ -45,7 +45,7 @@ impl Command for DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, @@ -61,7 +61,7 @@ impl DeleteTui { ) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &cmd.node_opts.at_node).await?; let tui = Self { - ctx: ctx.async_try_clone().await?, + ctx: ctx.try_clone()?, opts, node, cmd, diff --git a/implementations/rust/ockam/ockam_command/src/kafka/outlet/delete.rs b/implementations/rust/ockam/ockam_command/src/kafka/outlet/delete.rs index 42fdc4461a2..c10e834b9cf 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/outlet/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/outlet/delete.rs @@ -9,7 +9,7 @@ use ockam_api::nodes::models::services::{DeleteServiceRequest, ServiceStatus}; use ockam_api::nodes::BackgroundNodeClient; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_core::api::Request; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_node::Context; use crate::tui::{DeleteCommandTui, PluralTerm}; @@ -42,7 +42,7 @@ impl Command for DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, @@ -58,7 +58,7 @@ impl DeleteTui { ) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &cmd.node_opts.at_node).await?; let tui = Self { - ctx: ctx.async_try_clone().await?, + ctx: ctx.try_clone()?, opts, node, cmd, diff --git a/implementations/rust/ockam/ockam_command/src/message/send.rs b/implementations/rust/ockam/ockam_command/src/message/send.rs index 4cb8e6addc0..db70f5643ee 100644 --- a/implementations/rust/ockam/ockam_command/src/message/send.rs +++ b/implementations/rust/ockam/ockam_command/src/message/send.rs @@ -82,8 +82,7 @@ impl Command for SendCommand { // Setup environment depending on whether we are sending the message from a background node // or an in-memory node let response: Vec = if let Some(node) = &self.from { - BackgroundNodeClient::create_to_node(ctx, &opts.state, node.as_str()) - .await? + BackgroundNodeClient::create_to_node(ctx, &opts.state, node.as_str())? .send_message(ctx, &to, msg_bytes, Some(self.timeout.timeout)) .await .map_err(Error::Retry)? diff --git a/implementations/rust/ockam/ockam_command/src/node/create/background.rs b/implementations/rust/ockam/ockam_command/src/node/create/background.rs index 4397e729301..3d63999cb32 100644 --- a/implementations/rust/ockam/ockam_command/src/node/create/background.rs +++ b/implementations/rust/ockam/ockam_command/src/node/create/background.rs @@ -57,7 +57,7 @@ impl CreateCommand { ..self.clone() }; cmd_with_trace_context.spawn_background_node(&opts).await?; - let mut node = BackgroundNodeClient::create_to_node(ctx, &opts.state, &node_name).await?; + let mut node = BackgroundNodeClient::create_to_node(ctx, &opts.state, &node_name)?; let node_resources = get_node_resources(ctx, &opts.state, &mut node, true).await?; opts.state .add_journey_event( diff --git a/implementations/rust/ockam/ockam_command/src/node/create/config.rs b/implementations/rust/ockam/ockam_command/src/node/create/config.rs index da6e5c2f61d..47f46c8d0da 100644 --- a/implementations/rust/ockam/ockam_command/src/node/create/config.rs +++ b/implementations/rust/ockam/ockam_command/src/node/create/config.rs @@ -11,7 +11,7 @@ use nix::sys::signal; use ockam_api::cli_state::journeys::APPLICATION_EVENT_COMMAND_CONFIGURATION_FILE; use ockam_api::nodes::BackgroundNodeClient; use ockam_api::CliState; -use ockam_core::{AsyncTryClone, OpenTelemetryContext}; +use ockam_core::{OpenTelemetryContext, TryClone}; use ockam_node::Context; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -269,9 +269,8 @@ impl NodeConfig { // Wait for the node to be up let is_up = { - let ctx = ctx.async_try_clone().await.into_diagnostic()?; - let mut node = - BackgroundNodeClient::create_to_node(&ctx, &opts.state, node_name).await?; + let ctx = ctx.try_clone().into_diagnostic()?; + let mut node = BackgroundNodeClient::create_to_node(&ctx, &opts.state, node_name)?; is_node_up(&ctx, &mut node, true).await? }; if !is_up { diff --git a/implementations/rust/ockam/ockam_command/src/node/create/foreground.rs b/implementations/rust/ockam/ockam_command/src/node/create/foreground.rs index a02b1919caa..11a11e86534 100644 --- a/implementations/rust/ockam/ockam_command/src/node/create/foreground.rs +++ b/implementations/rust/ockam/ockam_command/src/node/create/foreground.rs @@ -59,7 +59,7 @@ impl CreateCommand { .into_diagnostic()?; // Create TCP transport - let tcp = TcpTransport::create(ctx).await.into_diagnostic()?; + let tcp = TcpTransport::create(ctx).into_diagnostic()?; let tcp_listener = tcp .listen(&self.tcp_listener_address, TcpListenerOptions::new()) .await @@ -81,7 +81,7 @@ impl CreateCommand { debug!("node info persisted {node_info:?}"); let udp_transport = if self.udp { - Some(UdpTransport::create(ctx).await.into_diagnostic()?) + Some(UdpTransport::create(ctx).into_diagnostic()?) } else { None }; @@ -108,9 +108,8 @@ impl CreateCommand { let node_manager_worker = NodeManagerWorker::new(Arc::new(node_man)); ctx.flow_controls() - .add_consumer(NODEMANAGER_ADDR, tcp_listener.flow_control_id()); + .add_consumer(&NODEMANAGER_ADDR.into(), tcp_listener.flow_control_id()); ctx.start_worker(NODEMANAGER_ADDR, node_manager_worker) - .await .into_diagnostic()?; debug!("node manager worker started"); @@ -124,7 +123,7 @@ impl CreateCommand { // and the other being terminated, so when restarted it works. This is // FAR from ideal. sleep(Duration::from_secs(10)).await; - ctx.stop().await.into_diagnostic()?; + ctx.shutdown_node().await.into_diagnostic()?; return Err(miette!("Failed to start services")); } diff --git a/implementations/rust/ockam/ockam_command/src/node/delete.rs b/implementations/rust/ockam/ockam_command/src/node/delete.rs index ff711d8d7ef..ebb2d2a4e9e 100644 --- a/implementations/rust/ockam/ockam_command/src/node/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/node/delete.rs @@ -9,7 +9,6 @@ use ockam_api::colors::color_primary; use ockam_api::fmt_ok; use ockam_api::terminal::notification::NotificationHandler; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_core::AsyncTryClone; const LONG_ABOUT: &str = include_str!("./static/delete/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); @@ -57,7 +56,7 @@ impl DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(Clone)] pub struct DeleteTui { opts: CommandGlobalOpts, cmd: DeleteCommand, diff --git a/implementations/rust/ockam/ockam_command/src/node/show.rs b/implementations/rust/ockam/ockam_command/src/node/show.rs index 5ccbc034bee..d2625573b04 100644 --- a/implementations/rust/ockam/ockam_command/src/node/show.rs +++ b/implementations/rust/ockam/ockam_command/src/node/show.rs @@ -13,7 +13,7 @@ use tracing::{info, trace, warn}; use ockam_api::nodes::models::node::{NodeResources, NodeStatus}; use ockam_api::nodes::BackgroundNodeClient; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_node::Context; use crate::terminal::tui::ShowCommandTui; @@ -66,7 +66,7 @@ impl ShowTui { node_name: Option, ) -> miette::Result<()> { let tui = Self { - ctx: ctx.async_try_clone().await.into_diagnostic()?, + ctx: ctx.try_clone().into_diagnostic()?, opts, node_name, }; diff --git a/implementations/rust/ockam/ockam_command/src/node/start.rs b/implementations/rust/ockam/ockam_command/src/node/start.rs index 4468ee9ab79..5cad5e3a02c 100644 --- a/implementations/rust/ockam/ockam_command/src/node/start.rs +++ b/implementations/rust/ockam/ockam_command/src/node/start.rs @@ -183,7 +183,7 @@ async fn run_node( }; spawn_node(opts, cmd).await?; - let node = BackgroundNodeClient::create_to_node(ctx, &opts.state, node_name).await?; + let node = BackgroundNodeClient::create_to_node(ctx, &opts.state, node_name)?; Ok(node) } diff --git a/implementations/rust/ockam/ockam_command/src/policy/delete.rs b/implementations/rust/ockam/ockam_command/src/policy/delete.rs index b9b0dc7851b..ac95fa061ee 100644 --- a/implementations/rust/ockam/ockam_command/src/policy/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/policy/delete.rs @@ -13,7 +13,7 @@ use ockam_api::fmt_ok; use ockam_api::nodes::models::policies::ResourceTypeOrName; use ockam_api::nodes::{BackgroundNodeClient, Policies}; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; @@ -47,7 +47,7 @@ impl DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, @@ -63,7 +63,7 @@ impl DeleteTui { ) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &cmd.at).await?; let tui = Self { - ctx: ctx.async_try_clone().await.into_diagnostic()?, + ctx: ctx.try_clone().into_diagnostic()?, opts, node, cmd, diff --git a/implementations/rust/ockam/ockam_command/src/policy/show.rs b/implementations/rust/ockam/ockam_command/src/policy/show.rs index 7689890ddfc..f1660520ddc 100644 --- a/implementations/rust/ockam/ockam_command/src/policy/show.rs +++ b/implementations/rust/ockam/ockam_command/src/policy/show.rs @@ -13,7 +13,7 @@ use ockam_api::fmt_ok; use ockam_api::nodes::models::policies::ResourceTypeOrName; use ockam_api::nodes::{BackgroundNodeClient, Policies}; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use crate::terminal::tui::ShowCommandTui; use crate::tui::PluralTerm; @@ -58,7 +58,7 @@ impl ShowTui { ) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &cmd.at).await?; let tui = Self { - ctx: ctx.async_try_clone().await.into_diagnostic()?, + ctx: ctx.try_clone().into_diagnostic()?, opts, node, resource: cmd.resource, diff --git a/implementations/rust/ockam/ockam_command/src/project/show.rs b/implementations/rust/ockam/ockam_command/src/project/show.rs index b2ca27341df..e64c10692dd 100644 --- a/implementations/rust/ockam/ockam_command/src/project/show.rs +++ b/implementations/rust/ockam/ockam_command/src/project/show.rs @@ -8,7 +8,7 @@ use ockam_api::cloud::project::ProjectsOrchestratorApi; use ockam_api::nodes::InMemoryNode; use ockam_api::output::Output; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use crate::shared_args::{IdentityOpts, RetryOpts}; use crate::terminal::tui::ShowCommandTui; @@ -47,12 +47,7 @@ impl Command for ShowCommand { } async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { - Ok(ShowTui::run( - ctx.async_try_clone().await.into_diagnostic()?, - opts, - self.name.clone(), - ) - .await?) + Ok(ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self.name.clone()).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/project_admin/delete.rs b/implementations/rust/ockam/ockam_command/src/project_admin/delete.rs index b86c672b3f3..ee59d09a7d5 100644 --- a/implementations/rust/ockam/ockam_command/src/project_admin/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/project_admin/delete.rs @@ -13,7 +13,7 @@ use ockam_api::colors::color_primary; use ockam_api::fmt_ok; use ockam_api::nodes::InMemoryNode; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use std::sync::Arc; /// Delete an Admin from a Project @@ -47,7 +47,7 @@ impl Command for DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] pub struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, @@ -75,7 +75,7 @@ impl DeleteTui { ) .await?; let tui = Self { - ctx: ctx.async_try_clone().await?, + ctx: ctx.try_clone()?, opts, node: Arc::new(node), cmd, diff --git a/implementations/rust/ockam/ockam_command/src/project_member/delete.rs b/implementations/rust/ockam/ockam_command/src/project_member/delete.rs index 9c9b5de3745..4f730a7d512 100644 --- a/implementations/rust/ockam/ockam_command/src/project_member/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/project_member/delete.rs @@ -10,7 +10,7 @@ use ockam::Context; use ockam_api::authenticator::direct::Members; use ockam_api::colors::color_primary; use ockam_api::{fmt_info, fmt_ok}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use serde::Serialize; use std::fmt::Display; use std::time::Duration; @@ -109,7 +109,7 @@ impl Command for DeleteCommand { let mut set: JoinSet> = JoinSet::new(); for identifier in chunk { let authority_node_client = authority_node_client.clone(); - let ctx = ctx.async_try_clone().await?; + let ctx = ctx.try_clone()?; set.spawn(async move { sleep(tokio_retry::strategy::jitter(Duration::from_millis(500))).await; if let Err(e) = authority_node_client diff --git a/implementations/rust/ockam/ockam_command/src/project_member/show.rs b/implementations/rust/ockam/ockam_command/src/project_member/show.rs index a1766324cb3..1fc544439c2 100644 --- a/implementations/rust/ockam/ockam_command/src/project_member/show.rs +++ b/implementations/rust/ockam/ockam_command/src/project_member/show.rs @@ -10,7 +10,7 @@ use ockam_api::authenticator::direct::Members; use ockam_api::cloud::AuthorityNodeClient; use ockam_api::output::Output; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use crate::project_member::{authority_client, MemberOutput}; use crate::shared_args::IdentityOpts; @@ -45,7 +45,7 @@ impl Command for ShowCommand { const NAME: &'static str = "project-member show"; async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { - Ok(ShowTui::run(ctx.async_try_clone().await.into_diagnostic()?, opts, self).await?) + Ok(ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/relay/delete.rs b/implementations/rust/ockam/ockam_command/src/relay/delete.rs index a7ecc193678..9b2332601fb 100644 --- a/implementations/rust/ockam/ockam_command/src/relay/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/relay/delete.rs @@ -12,7 +12,7 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_api::{color, fmt_ok}; use ockam_core::api::Request; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; @@ -49,16 +49,11 @@ impl DeleteCommand { } pub async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { - DeleteTui::run( - ctx.async_try_clone().await.into_diagnostic()?, - opts, - self.clone(), - ) - .await + DeleteTui::run(ctx.try_clone().into_diagnostic()?, opts, self.clone()).await } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, diff --git a/implementations/rust/ockam/ockam_command/src/relay/show.rs b/implementations/rust/ockam/ockam_command/src/relay/show.rs index 4ef226bfec7..60addba1579 100644 --- a/implementations/rust/ockam/ockam_command/src/relay/show.rs +++ b/implementations/rust/ockam/ockam_command/src/relay/show.rs @@ -15,7 +15,7 @@ use ockam_api::colors::OckamColor; use ockam_api::output::Output; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_api::ConnectionStatus; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use serde::Serialize; use crate::terminal::tui::ShowCommandTui; @@ -52,12 +52,7 @@ impl ShowCommand { } async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { - ShowTui::run( - ctx.async_try_clone().await.into_diagnostic()?, - opts, - self.clone(), - ) - .await + ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self.clone()).await } } diff --git a/implementations/rust/ockam/ockam_command/src/rendezvous/create/foreground.rs b/implementations/rust/ockam/ockam_command/src/rendezvous/create/foreground.rs index 080cd9df8c4..622166e2f08 100644 --- a/implementations/rust/ockam/ockam_command/src/rendezvous/create/foreground.rs +++ b/implementations/rust/ockam/ockam_command/src/rendezvous/create/foreground.rs @@ -23,11 +23,9 @@ impl CreateCommand { udp_address ); - RendezvousService::start(ctx, DefaultAddress::RENDEZVOUS_SERVICE) - .await - .into_diagnostic()?; + RendezvousService::start(ctx, DefaultAddress::RENDEZVOUS_SERVICE).into_diagnostic()?; - let udp = UdpTransport::create(ctx).await.into_diagnostic()?; + let udp = UdpTransport::create(ctx).into_diagnostic()?; let bind = udp .bind( UdpBindArguments::new().with_bind_socket_address(udp_address), @@ -36,12 +34,13 @@ impl CreateCommand { .await .into_diagnostic()?; - ctx.flow_controls() - .add_consumer(DefaultAddress::RENDEZVOUS_SERVICE, bind.flow_control_id()); + ctx.flow_controls().add_consumer( + &DefaultAddress::RENDEZVOUS_SERVICE.into(), + bind.flow_control_id(), + ); let mut healthcheck = RendezvousHealthcheck::create(&self.healthcheck_address, &udp, udp_address) - .await .into_diagnostic()?; healthcheck.start().await.into_diagnostic()?; diff --git a/implementations/rust/ockam/ockam_command/src/rendezvous/get_my_address.rs b/implementations/rust/ockam/ockam_command/src/rendezvous/get_my_address.rs index e136f47ce02..edba3b28271 100644 --- a/implementations/rust/ockam/ockam_command/src/rendezvous/get_my_address.rs +++ b/implementations/rust/ockam/ockam_command/src/rendezvous/get_my_address.rs @@ -20,7 +20,7 @@ impl Command for GetMyAddressCommand { const NAME: &'static str = "rendezvous get-my-address"; async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { - let udp = UdpTransport::create(ctx).await?; + let udp = UdpTransport::create(ctx)?; let bind = udp .bind( UdpBindArguments::new().with_bind_address("0.0.0.0:0")?, diff --git a/implementations/rust/ockam/ockam_command/src/run/parser/resource/traits.rs b/implementations/rust/ockam/ockam_command/src/run/parser/resource/traits.rs index b6ec42b352b..f062ad53a87 100644 --- a/implementations/rust/ockam/ockam_command/src/run/parser/resource/traits.rs +++ b/implementations/rust/ockam/ockam_command/src/run/parser/resource/traits.rs @@ -7,7 +7,7 @@ use crate::{Command, CommandGlobalOpts, GlobalArgs}; use async_trait::async_trait; use miette::{IntoDiagnostic, Result}; use ockam_api::colors::color_primary; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_node::Context; use tokio::process::{Child, Command as ProcessCommand}; use tracing::debug; @@ -121,7 +121,7 @@ impl ParsedCommands { pub async fn run(self, ctx: &Context, opts: &CommandGlobalOpts) -> Result<()> { for cmd in self.commands.into_iter() { if cmd.is_valid(ctx, opts).await? { - let ctx = ctx.async_try_clone().await.into_diagnostic()?; + let ctx = ctx.try_clone().into_diagnostic()?; cmd.run(&ctx, opts).await?; // Newline between commands opts.terminal.write_line("")?; diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/create.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/create.rs index a90259c7ba7..dee6a3d17a8 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/create.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/create.rs @@ -101,7 +101,7 @@ impl CreateCommand { async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { initialize_default_node(ctx, &opts).await?; - let node = BackgroundNodeClient::create_to_node(ctx, &opts.state, &self.from).await?; + let node = BackgroundNodeClient::create_to_node(ctx, &opts.state, &self.from)?; opts.terminal .write_line(fmt_log!("Creating Secure Channel...\n"))?; diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/create.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/create.rs index 09441c62611..ac7871351f7 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/create.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/create.rs @@ -105,7 +105,7 @@ pub async fn create_listener( ) -> miette::Result<()> { let resp: Vec = ctx .send_and_receive( - base_route.modify().append(NODEMANAGER_ADDR), + base_route + NODEMANAGER_ADDR, api::create_secure_channel_listener(&addr, authorized_identifiers, identity)?, ) .await diff --git a/implementations/rust/ockam/ockam_command/src/space/delete.rs b/implementations/rust/ockam/ockam_command/src/space/delete.rs index 3efd2149057..ac79da0ce65 100644 --- a/implementations/rust/ockam/ockam_command/src/space/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/space/delete.rs @@ -14,7 +14,7 @@ use ockam_api::colors::OckamColor; use ockam_api::nodes::InMemoryNode; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_api::{color, fmt_ok}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; const LONG_ABOUT: &str = include_str!("./static/delete/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); @@ -48,7 +48,7 @@ impl Command for DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] pub struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, @@ -64,7 +64,7 @@ impl DeleteTui { ) -> miette::Result<()> { let node = InMemoryNode::start(ctx, &opts.state).await?; let tui = Self { - ctx: ctx.async_try_clone().await?, + ctx: ctx.try_clone()?, opts, node: Arc::new(node), cmd, diff --git a/implementations/rust/ockam/ockam_command/src/space_admin/delete.rs b/implementations/rust/ockam/ockam_command/src/space_admin/delete.rs index a69a7e29af4..9dbcb7712da 100644 --- a/implementations/rust/ockam/ockam_command/src/space_admin/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/space_admin/delete.rs @@ -13,7 +13,7 @@ use ockam_api::colors::color_primary; use ockam_api::nodes::InMemoryNode; use ockam_api::terminal::{ConfirmResult, Terminal, TerminalStream}; use ockam_api::{fmt_ok, fmt_warn}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use std::sync::Arc; /// Delete an Admin from a Space @@ -47,7 +47,7 @@ impl Command for DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] pub struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, @@ -84,7 +84,7 @@ impl DeleteTui { } let tui = Self { - ctx: ctx.async_try_clone().await?, + ctx: ctx.try_clone()?, opts, node: Arc::new(node), cmd, diff --git a/implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs b/implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs index 5a8520211b3..7e849053e87 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs @@ -14,7 +14,7 @@ use ockam_api::nodes::service::tcp_inlets::Inlets; use ockam_api::nodes::BackgroundNodeClient; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_core::api::Request; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; @@ -51,7 +51,7 @@ impl Command for DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, @@ -67,7 +67,7 @@ impl DeleteTui { ) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &cmd.node_opts.at_node).await?; let tui = Self { - ctx: ctx.async_try_clone().await?, + ctx: ctx.try_clone()?, opts, node, cmd, diff --git a/implementations/rust/ockam/ockam_command/src/tcp/inlet/show.rs b/implementations/rust/ockam/ockam_command/src/tcp/inlet/show.rs index 62c1650aac8..26d4a8f41ad 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/inlet/show.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/inlet/show.rs @@ -12,7 +12,7 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_api::output::Output; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_core::api::Request; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/show/after_long_help.txt"); @@ -37,12 +37,7 @@ impl Command for ShowCommand { const NAME: &'static str = "tcp-inlet show"; async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { - Ok(ShowTui::run( - ctx.async_try_clone().await.into_diagnostic()?, - opts, - self.clone(), - ) - .await?) + Ok(ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self.clone()).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/tcp/outlet/delete.rs b/implementations/rust/ockam/ockam_command/src/tcp/outlet/delete.rs index 4029b8a9ef9..b4da0908eb9 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/outlet/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/outlet/delete.rs @@ -13,7 +13,7 @@ use ockam_api::nodes::models::portal::OutletStatus; use ockam_api::nodes::BackgroundNodeClient; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_core::api::Request; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; @@ -56,7 +56,7 @@ impl Command for DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(TryClone)] pub struct DeleteTui { ctx: Context, opts: CommandGlobalOpts, @@ -72,7 +72,7 @@ impl DeleteTui { ) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &cmd.node_opts.at_node).await?; let tui = Self { - ctx: ctx.async_try_clone().await?, + ctx: ctx.try_clone()?, opts, cmd, node, diff --git a/implementations/rust/ockam/ockam_command/src/tcp/outlet/show.rs b/implementations/rust/ockam/ockam_command/src/tcp/outlet/show.rs index 83152fc05df..eee4cb8e8cb 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/outlet/show.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/outlet/show.rs @@ -11,7 +11,7 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_api::{address::extract_address_value, nodes::models::portal::OutletStatus}; use ockam_core::api::Request; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use ockam_multiaddr::MultiAddr; use crate::tcp::util::alias_parser; @@ -46,12 +46,7 @@ impl Command for ShowCommand { const NAME: &'static str = "tcp-outlet show"; async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { - Ok(ShowTui::run( - ctx.async_try_clone().await.into_diagnostic()?, - opts, - self.clone(), - ) - .await?) + Ok(ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self.clone()).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/terminal/tui.rs b/implementations/rust/ockam/ockam_command/src/terminal/tui.rs index 52af53cfd7b..cfa0966a565 100644 --- a/implementations/rust/ockam/ockam_command/src/terminal/tui.rs +++ b/implementations/rust/ockam/ockam_command/src/terminal/tui.rs @@ -4,7 +4,7 @@ use miette::{miette, IntoDiagnostic}; use ockam_api::colors::color_primary; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_api::{fmt_info, fmt_warn}; -use ockam_core::AsyncTryClone; +use ockam_core::TryClone; use std::time::Duration; use tokio::task::JoinSet; use tokio::time::sleep; @@ -112,7 +112,7 @@ fn get_opt_node_name_message(node_name: Option<&str>) -> String { } #[ockam_core::async_trait] -pub trait DeleteCommandTui: AsyncTryClone + Send +pub trait DeleteCommandTui: TryClone + Send where Self: 'static, { @@ -149,7 +149,7 @@ where for chunk in items_names.chunks(10).map(|c| c.to_vec()) { let mut set: JoinSet> = JoinSet::new(); for item_name in chunk { - let _self = self.async_try_clone().await.into_diagnostic()?; + let _self = self.try_clone().into_diagnostic()?; set.spawn(async move { sleep(tokio_retry::strategy::jitter(Duration::from_millis(500))).await; if _self.delete_single(&item_name).await.is_err() { diff --git a/implementations/rust/ockam/ockam_command/src/util/mod.rs b/implementations/rust/ockam/ockam_command/src/util/mod.rs index 195615a72c2..0674bcab91f 100644 --- a/implementations/rust/ockam/ockam_command/src/util/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/util/mod.rs @@ -67,10 +67,9 @@ where DenyAll, DenyAll, ) - .await .expect("Embedded node child ctx can't be created"); let r = f(child_ctx).await; - let _ = ctx.stop().await; + let _ = ctx.shutdown_node().await; r } .with_context(OpenTelemetryContext::current_context()), @@ -96,10 +95,9 @@ where DenyAll, DenyAll, ) - .await .expect("Embedded node child ctx can't be created"); let result = f(child_ctx).await; - let _ = ctx.stop().await; + let _ = ctx.shutdown_node().await; result.map_err(|e| { ockam_core::Error::new( ockam_core::errcode::Origin::Executor, @@ -292,7 +290,7 @@ mod tests { ctx: Context, _parameter: u8, ) -> miette::Result<()> { - ctx.stop().await.into_diagnostic()?; + ctx.shutdown_node().await.into_diagnostic()?; Err(miette!("boom")) } } diff --git a/implementations/rust/ockam/ockam_command/src/vault/delete.rs b/implementations/rust/ockam/ockam_command/src/vault/delete.rs index 4f6dda695f7..ec20e7f4a4f 100644 --- a/implementations/rust/ockam/ockam_command/src/vault/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/vault/delete.rs @@ -8,7 +8,6 @@ use console::Term; use ockam_api::colors::OckamColor; use ockam_api::terminal::{Terminal, TerminalStream}; use ockam_api::{color, fmt_ok}; -use ockam_core::AsyncTryClone; const LONG_ABOUT: &str = include_str!("./static/delete/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); @@ -47,7 +46,7 @@ impl DeleteCommand { } } -#[derive(AsyncTryClone)] +#[derive(Clone)] pub struct DeleteTui { opts: CommandGlobalOpts, cmd: DeleteCommand, diff --git a/implementations/rust/ockam/ockam_core/Cargo.toml b/implementations/rust/ockam/ockam_core/Cargo.toml index 17d11801368..d5c2b9c320e 100644 --- a/implementations/rust/ockam/ockam_core/Cargo.toml +++ b/implementations/rust/ockam/ockam_core/Cargo.toml @@ -76,7 +76,7 @@ backtrace = { version = "0.3", default-features = false, features = ["std", "ser cfg-if = "1.0" core2 = { version = "0.4.0", default-features = false, optional = true } futures-util = { version = "0.3.30", default-features = false, features = ["alloc", "async-await-macro", "sink"] } -hashbrown = { version = "0.14", default-features = false, features = ["ahash", "serde"] } +hashbrown = { version = "0.15.2", features = ["serde", "default-hasher", "equivalent"] } hex = { version = "0.4", default-features = false, optional = true } miette = { version = "7.2.0", features = ["fancy-no-backtrace"], optional = true } minicbor = { version = "0.25.1", default-features = false, features = ["derive"] } diff --git a/implementations/rust/ockam/ockam_core/src/access_control/cache.rs b/implementations/rust/ockam/ockam_core/src/access_control/cache.rs index 08245fc4c8d..e2f49e2af0f 100644 --- a/implementations/rust/ockam/ockam_core/src/access_control/cache.rs +++ b/implementations/rust/ockam/ockam_core/src/access_control/cache.rs @@ -27,7 +27,7 @@ impl CacheEntry { destination: relay_message.destination().clone(), onward_route: relay_message.onward_route().clone(), return_route: relay_message.return_route().clone(), - local_info: relay_message.local_message().local_info(), + local_info: relay_message.local_message().local_info().to_vec(), timestamp: Instant::now(), } } @@ -44,7 +44,7 @@ impl CacheEntry { && self.destination == *relay_message.destination() && self.onward_route == *relay_message.onward_route() && self.return_route == *relay_message.return_route() - && self.local_info == relay_message.local_message().local_info_ref() + && self.local_info == relay_message.local_message().local_info() } } diff --git a/implementations/rust/ockam/ockam_core/src/api.rs b/implementations/rust/ockam/ockam_core/src/api.rs index 63c144ebc17..7409c3e188d 100644 --- a/implementations/rust/ockam/ockam_core/src/api.rs +++ b/implementations/rust/ockam/ockam_core/src/api.rs @@ -125,7 +125,7 @@ impl Serialize for Reply { match self { Reply::Successful(t) => t.serialize(serializer), Reply::Failed(e, Some(s)) => { - let mut map = HashMap::new(); + let mut map: HashMap<&str, String> = Default::default(); map.insert("error", e.to_string()); map.insert("status", s.to_string()); serializer.collect_map(map) diff --git a/implementations/rust/ockam/ockam_core/src/compat.rs b/implementations/rust/ockam/ockam_core/src/compat.rs index 1fba92283d5..37a3a7c7765 100644 --- a/implementations/rust/ockam/ockam_core/src/compat.rs +++ b/implementations/rust/ockam/ockam_core/src/compat.rs @@ -30,6 +30,18 @@ pub mod collections { pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}; pub use hashbrown::{HashMap, HashSet}; + + /// hash map + pub mod hash_map { + pub use hashbrown::hash_map::{Entry, EntryRef}; + pub use hashbrown::Equivalent; + } + + /// btree map + #[cfg(feature = "alloc")] + pub mod btree_map { + pub use alloc::collections::btree_map::Entry; + } } /// Provides a `std::error::Error` trait. @@ -224,7 +236,7 @@ pub mod str { pub mod sync { use core::convert::Infallible; - pub use alloc::sync::Arc; + pub use alloc::sync::{Arc, Weak}; /// Wrap `spin::RwLock` as it does not return LockResult like `std::sync::Mutex`. #[derive(Debug)] @@ -254,6 +266,11 @@ pub mod sync { Self::new(Default::default()) } } + impl From for RwLock { + fn from(t: T) -> Self { + Self::new(t) + } + } impl core::ops::Deref for RwLock { type Target = spin::RwLock; fn deref(&self) -> &spin::RwLock { @@ -289,12 +306,25 @@ pub mod sync { &mut self.0 } } + impl Default for Mutex + where + T: Default, + { + fn default() -> Self { + Self::new(Default::default()) + } + } + impl From for Mutex { + fn from(t: T) -> Self { + Self::new(t) + } + } } /// Provides `std::sync` for `std` targets. #[cfg(feature = "std")] pub mod sync { - pub use std::sync::Arc; - pub use std::sync::{Mutex, RwLock, RwLockWriteGuard}; + pub use std::sync::{Arc, Weak}; + pub use std::sync::{Mutex, RwLock}; } /// Provides `std::task` for `no_std` targets. diff --git a/implementations/rust/ockam/ockam_core/src/flow_control/flow_control_id.rs b/implementations/rust/ockam/ockam_core/src/flow_control/flow_control_id.rs index 4769b7b4e77..5c657fa7c96 100644 --- a/implementations/rust/ockam/ockam_core/src/flow_control/flow_control_id.rs +++ b/implementations/rust/ockam/ockam_core/src/flow_control/flow_control_id.rs @@ -7,7 +7,7 @@ use minicbor::{CborLen, Decode, Encode}; use serde::{Deserialize, Serialize}; /// Unique random identifier of a Flow Control -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, CborLen)] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Encode, Decode, CborLen)] #[rustfmt::skip] #[cbor(map)] pub struct FlowControlId { diff --git a/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/flow_controls.rs b/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/flow_controls.rs index 156bf092490..ceacba18192 100644 --- a/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/flow_controls.rs +++ b/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/flow_controls.rs @@ -1,4 +1,4 @@ -use crate::compat::collections::BTreeMap; +use crate::compat::collections::HashMap; use crate::compat::sync::{Arc, RwLock}; use crate::flow_control::{ConsumersInfo, FlowControlId, ProducerInfo}; use crate::Address; @@ -7,12 +7,12 @@ use crate::Address; #[derive(Clone, Debug)] pub struct FlowControls { // All known consumers - pub(super) consumers: Arc>>, + pub(super) consumers: Arc>>, // All known producers - pub(super) producers: Arc>>, + pub(super) producers: Arc>>, // Allows to find producer by having its additional Address, // e.g. Decryptor by its Encryptor Address or TCP Receiver by its TCP Sender Address - pub(super) producers_additional_addresses: Arc>>, + pub(super) producers_additional_addresses: Arc>>, // All known spawners - pub(super) spawners: Arc>>, + pub(super) spawners: Arc>>, } diff --git a/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/flow_controls_api.rs b/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/flow_controls_api.rs index 343180cfae6..b23006c9a14 100644 --- a/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/flow_controls_api.rs +++ b/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/flow_controls_api.rs @@ -23,8 +23,7 @@ impl FlowControls { } /// Mark that given [`Address`] is a Consumer for a Producer with the given [`FlowControlId`] - pub fn add_consumer(&self, address: impl Into
, flow_control_id: &FlowControlId) { - let address = address.into(); + pub fn add_consumer(&self, address: &Address, flow_control_id: &FlowControlId) { let mut consumers = self.consumers.write().unwrap(); if !consumers.contains_key(flow_control_id) { consumers.insert(flow_control_id.clone(), Default::default()); @@ -42,12 +41,11 @@ impl FlowControls { /// with the given spawner [`FlowControlId`] (if that's the case). pub fn add_producer( &self, - address: impl Into
, + address: &Address, flow_control_id: &FlowControlId, spawner_flow_control_id: Option<&FlowControlId>, additional_addresses: Vec
, ) { - let address = address.into(); let mut producers = self.producers.write().unwrap(); let is_new = producers .insert( @@ -77,9 +75,7 @@ impl FlowControls { } /// Mark that given [`Address`] is a Spawner for to the given [`FlowControlId`] - pub fn add_spawner(&self, address: impl Into
, flow_control_id: &FlowControlId) { - let address = address.into(); - + pub fn add_spawner(&self, address: &Address, flow_control_id: &FlowControlId) { let mut spawners = self.spawners.write().unwrap(); if spawners diff --git a/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/tests.rs b/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/tests.rs index 589d62aa26b..fb42c0746f1 100644 --- a/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/tests.rs +++ b/implementations/rust/ockam/ockam_core/src/flow_control/flow_controls/tests.rs @@ -15,7 +15,7 @@ fn add_random_consumer(flow_controls: &FlowControls, mut rng: &mut ThreadRng) -> // Add a Consumer to a non-existent FlowControlId let flow_control_id = FlowControls::generate_flow_control_id(); - flow_controls.add_consumer(address.clone(), &flow_control_id); + flow_controls.add_consumer(&address, &flow_control_id); vec![address] } @@ -30,7 +30,7 @@ fn add_random_consumer(flow_controls: &FlowControls, mut rng: &mut ThreadRng) -> .cloned(); match spawner_flow_control_id { Some(spawner_flow_control_id) => { - flow_controls.add_consumer(address.clone(), &spawner_flow_control_id); + flow_controls.add_consumer(&address, &spawner_flow_control_id); vec![address] } _ => vec![], @@ -49,7 +49,7 @@ fn add_random_consumer(flow_controls: &FlowControls, mut rng: &mut ThreadRng) -> match producer_flow_control_id { None => vec![], Some(producer_flow_control_id) => { - flow_controls.add_consumer(address.clone(), &producer_flow_control_id); + flow_controls.add_consumer(&address, &producer_flow_control_id); vec![address] } } @@ -67,7 +67,7 @@ fn add_random_spawner(flow_controls: &FlowControls, mut rng: &mut ThreadRng) -> // Add a Spawner to a new FlowControlId let flow_control_id = FlowControls::generate_flow_control_id(); - flow_controls.add_spawner(address.clone(), &flow_control_id); + flow_controls.add_spawner(&address, &flow_control_id); vec![address] } else { @@ -82,7 +82,7 @@ fn add_random_spawner(flow_controls: &FlowControls, mut rng: &mut ThreadRng) -> match spawner_flow_control_id { Some(spawner_flow_control_id) => { - flow_controls.add_spawner(address.clone(), &spawner_flow_control_id); + flow_controls.add_spawner(&address, &spawner_flow_control_id); vec![address] } _ => vec![], @@ -99,7 +99,7 @@ fn add_random_producer(flow_controls: &FlowControls, mut rng: &mut ThreadRng) -> // Add a Producer without a Spawner let flow_control_id = FlowControls::generate_flow_control_id(); - flow_controls.add_producer(address.clone(), &flow_control_id, None, vec![]); + flow_controls.add_producer(&address, &flow_control_id, None, vec![]); vec![address] } else { @@ -120,7 +120,7 @@ fn add_random_producer(flow_controls: &FlowControls, mut rng: &mut ThreadRng) -> if choice2 < 0.5 { // No additional address flow_controls.add_producer( - address.clone(), + &address, &flow_control_id, Some(&spawner_flow_control_id), vec![], @@ -130,7 +130,7 @@ fn add_random_producer(flow_controls: &FlowControls, mut rng: &mut ThreadRng) -> // Random additional address let additional_address = Address::random_local(); flow_controls.add_producer( - address.clone(), + &address, &flow_control_id, Some(&spawner_flow_control_id), vec![additional_address.clone()], diff --git a/implementations/rust/ockam/ockam_core/src/identity/secure_channel_local_info.rs b/implementations/rust/ockam/ockam_core/src/identity/secure_channel_local_info.rs index 8debffd75e0..3e13b660e82 100644 --- a/implementations/rust/ockam/ockam_core/src/identity/secure_channel_local_info.rs +++ b/implementations/rust/ockam/ockam_core/src/identity/secure_channel_local_info.rs @@ -59,7 +59,7 @@ impl SecureChannelLocalInfo { /// Find `IdentitySecureChannelLocalInfo` in a list of general `LocalInfo` of that `LocalMessage` pub fn find_info(local_msg: &LocalMessage) -> Result { - Self::find_info_from_list(local_msg.local_info_ref()) + Self::find_info_from_list(local_msg.local_info()) } /// Find `IdentitySecureChannelLocalInfo` in a list of general `LocalInfo` diff --git a/implementations/rust/ockam/ockam_core/src/identity/secure_channel_metadata.rs b/implementations/rust/ockam/ockam_core/src/identity/secure_channel_metadata.rs index d03f3b83ad6..12b8958205a 100644 --- a/implementations/rust/ockam/ockam_core/src/identity/secure_channel_metadata.rs +++ b/implementations/rust/ockam/ockam_core/src/identity/secure_channel_metadata.rs @@ -1,6 +1,6 @@ use crate::compat::string::{String, ToString}; use crate::errcode::{Kind, Origin}; -use crate::{AddressAndMetadata, Error, LocalInfoIdentifier, Result, SECURE_CHANNEL_IDENTIFIER}; +use crate::{AddressMetadata, Error, LocalInfoIdentifier, Result, SECURE_CHANNEL_IDENTIFIER}; /// SecureChannel Metadata used for Terminal Address pub struct SecureChannelMetadata { @@ -34,19 +34,15 @@ impl SecureChannelMetadata { } /// Get the Identifier of the other side of the Secure Channel - pub fn from_terminal_address(terminal: &AddressAndMetadata) -> Result { + pub fn from_terminal_address_metadata(terminal: &AddressMetadata) -> Result { let identifier = if let Some(identifier) = - terminal - .metadata - .attributes - .iter() - .find_map(|(key, value)| { - if key == SECURE_CHANNEL_IDENTIFIER { - Some(value.clone()) - } else { - None - } - }) { + terminal.attributes.iter().find_map(|(key, value)| { + if key == SECURE_CHANNEL_IDENTIFIER { + Some(value.clone()) + } else { + None + } + }) { identifier } else { return Err(Self::error_type_id()); diff --git a/implementations/rust/ockam/ockam_core/src/lib.rs b/implementations/rust/ockam/ockam_core/src/lib.rs index a72fec734a6..8b9aa00cf4d 100644 --- a/implementations/rust/ockam/ockam_core/src/lib.rs +++ b/implementations/rust/ockam/ockam_core/src/lib.rs @@ -57,7 +57,7 @@ pub use async_trait::async_trait as processor; extern crate ockam_macros; -pub use ockam_macros::{AsyncTryClone, Message}; +pub use ockam_macros::{Message, TryClone}; extern crate futures_util; @@ -105,21 +105,17 @@ pub use compat::println; #[doc(hidden)] pub use std::println; -use crate::compat::boxed::Box; - -/// Clone trait for async structs. -#[async_trait] -pub trait AsyncTryClone: Sized { - /// Try cloning a object and return an `Err` in case of failure. - async fn async_try_clone(&self) -> Result; +/// Clone trait when clone can fail. +pub trait TryClone: Sized { + /// Try cloning an object and return an `Err` in case of failure. + fn try_clone(&self) -> Result; } -#[async_trait] -impl AsyncTryClone for D +impl TryClone for D where D: Clone + Sync, { - async fn async_try_clone(&self) -> Result { + fn try_clone(&self) -> Result { Ok(self.clone()) } } diff --git a/implementations/rust/ockam/ockam_core/src/message.rs b/implementations/rust/ockam/ockam_core/src/message.rs index ad08f0800e6..ded39a1a60a 100644 --- a/implementations/rust/ockam/ockam_core/src/message.rs +++ b/implementations/rust/ockam/ockam_core/src/message.rs @@ -262,7 +262,7 @@ impl Routed { /// Return a reference to the underlying transport message's binary payload. #[inline] pub fn payload(&self) -> &[u8] { - self.local_msg.payload_ref() + self.local_msg.payload() } /// Consume the message wrapper and return the underlying transport message's binary payload. diff --git a/implementations/rust/ockam/ockam_core/src/routing/address.rs b/implementations/rust/ockam/ockam_core/src/routing/address.rs index 03cf25b8061..ee48d2f1068 100644 --- a/implementations/rust/ockam/ockam_core/src/routing/address.rs +++ b/implementations/rust/ockam/ockam_core/src/routing/address.rs @@ -40,6 +40,12 @@ pub struct Address { #[n(1)] inner: Vec, } +impl AsRef
for Address { + fn as_ref(&self) -> &Address { + self + } +} + impl Address { /// Creates a new address from separate transport type and data parts. /// diff --git a/implementations/rust/ockam/ockam_core/src/routing/address_meta.rs b/implementations/rust/ockam/ockam_core/src/routing/address_meta.rs index 843816166ec..9d5ca25683a 100644 --- a/implementations/rust/ockam/ockam_core/src/routing/address_meta.rs +++ b/implementations/rust/ockam/ockam_core/src/routing/address_meta.rs @@ -1,9 +1,8 @@ use crate::compat::string::String; use crate::compat::vec::Vec; -use crate::Address; /// Additional metadata for address -#[derive(Debug, Clone, Eq, PartialEq, Default)] +#[derive(Debug, Clone, Eq, PartialEq)] pub struct AddressMetadata { /// Indicates that this Address will forward message to another route, therefore the next /// hop after this one belongs to another node @@ -11,12 +10,3 @@ pub struct AddressMetadata { /// Arbitrary set of attributes pub attributes: Vec<(String, String)>, } - -/// A set of metadata for a particular address -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct AddressAndMetadata { - /// Address - pub address: Address, - /// Metadata - pub metadata: AddressMetadata, -} diff --git a/implementations/rust/ockam/ockam_core/src/routing/macros.rs b/implementations/rust/ockam/ockam_core/src/routing/macros.rs index 51823287ca7..81e32c4efb6 100644 --- a/implementations/rust/ockam/ockam_core/src/routing/macros.rs +++ b/implementations/rust/ockam/ockam_core/src/routing/macros.rs @@ -17,7 +17,7 @@ macro_rules! route { ($($x:expr),* $(,)?) => ({ #[allow(unused_mut)] let mut r = $crate::Route::new(); - $(r = r.append_route($x.into());)* + $(r = r.append($x);)* $crate::Route::from(r) }); } @@ -36,20 +36,11 @@ mod tests { fn test2() { use crate::compat::string::ToString; let address: Address = random(); - let route1 = route!["str", "STR2", "STR3".to_string(), address]; - let _route2 = route![route1.clone(), "str1", route1]; + let _route1 = route!["str", "STR2", "STR3".to_string(), address]; } #[test] fn test3() { let _route = route!["str",]; } - - #[test] - fn test4() { - let route1 = route!["s1", "s2"]; - let route2 = route!["s4"]; - let route3 = route![route1, "s3", route2]; - assert_eq!(route3, route!["s1", "s2", "s3", "s4"]) - } } diff --git a/implementations/rust/ockam/ockam_core/src/routing/mailbox.rs b/implementations/rust/ockam/ockam_core/src/routing/mailbox.rs index 098a59f02a8..86ce9b883e3 100644 --- a/implementations/rust/ockam/ockam_core/src/routing/mailbox.rs +++ b/implementations/rust/ockam/ockam_core/src/routing/mailbox.rs @@ -1,6 +1,8 @@ use crate::access_control::IncomingAccessControl; use crate::compat::{sync::Arc, vec::Vec}; -use crate::{debugger, Address, DenyAll, OutgoingAccessControl, RelayMessage, Result}; +use crate::{ + debugger, Address, AddressMetadata, DenyAll, OutgoingAccessControl, RelayMessage, Result, +}; use core::cmp::Ordering; use core::fmt::{self, Debug}; @@ -10,6 +12,7 @@ use core::fmt::{self, Debug}; #[derive(Clone)] pub struct Mailbox { address: Address, + metadata: Option, incoming: Arc, outgoing: Arc, } @@ -48,11 +51,13 @@ impl Mailbox { /// Create a new `Mailbox` with the given [`Address`], [`IncomingAccessControl`] and [`OutgoingAccessControl`] pub fn new( address: impl Into
, + metadata: Option, incoming: Arc, outgoing: Arc, ) -> Self { Self { address: address.into(), + metadata, incoming, outgoing, } @@ -62,6 +67,7 @@ impl Mailbox { pub fn deny_all(address: impl Into
) -> Self { Self { address: address.into(), + metadata: Default::default(), incoming: Arc::new(DenyAll), outgoing: Arc::new(DenyAll), } @@ -81,12 +87,17 @@ impl Mailbox { pub fn outgoing_access_control(&self) -> &Arc { &self.outgoing } + + /// Metadata + pub fn metadata(&self) -> &Option { + &self.metadata + } } /// A collection of [`Mailbox`]es for a specific [`Worker`](crate::Worker), [`Processor`](crate::Processor) or `Context` #[derive(Clone)] pub struct Mailboxes { - main_mailbox: Mailbox, + primary_mailbox: Mailbox, additional_mailboxes: Vec, } @@ -95,30 +106,31 @@ impl Debug for Mailboxes { write!( f, "{:?} + {:?}", - self.main_mailbox, self.additional_mailboxes + self.primary_mailbox, self.additional_mailboxes ) } } impl Mailboxes { - /// Create [`Mailboxes`] given main [`Mailbox`] and collection of additional [`Mailbox`]es - pub fn new(main_mailbox: Mailbox, additional_mailboxes: Vec) -> Self { + /// Create [`Mailboxes`] given primary [`Mailbox`] and collection of additional [`Mailbox`]es + pub fn new(primary_mailbox: Mailbox, additional_mailboxes: Vec) -> Self { Self { - main_mailbox, + primary_mailbox, additional_mailboxes, } } - /// Create [`Mailboxes`] with only main [`Mailbox`] for the given + /// Create [`Mailboxes`] with only primary [`Mailbox`] for the given /// [`Address`] with [`IncomingAccessControl`] and [`OutgoingAccessControl`] - pub fn main( + pub fn primary( address: impl Into
, incoming_access_control: Arc, outgoing_access_control: Arc, ) -> Self { Self { - main_mailbox: Mailbox::new( + primary_mailbox: Mailbox::new( address.into(), + None, incoming_access_control, outgoing_access_control, ), @@ -127,26 +139,18 @@ impl Mailboxes { } /// Return all additional [`Address`]es represented by these [`Mailboxes`] - pub fn additional_addresses(&self) -> Vec
{ - self.additional_mailboxes - .iter() - .map(|x| x.address.clone()) - .collect() - } - - /// Return the main [`Address`] of this [`Mailboxes`] - pub fn main_address(&self) -> Address { - self.main_mailbox.address.clone() + pub fn additional_addresses(&self) -> impl Iterator { + self.additional_mailboxes.iter().map(|x| &x.address) } - /// Return the main [`Address`] of this [`Mailboxes`] - pub fn main_address_ref(&self) -> &Address { - &self.main_mailbox.address + /// Return the primary [`Address`] of this [`Mailboxes`] + pub fn primary_address(&self) -> &Address { + &self.primary_mailbox.address } /// Return `true` if the given [`Address`] is included in this [`Mailboxes`] pub fn contains(&self, msg_addr: &Address) -> bool { - if &self.main_mailbox.address == msg_addr { + if &self.primary_mailbox.address == msg_addr { true } else { self.additional_mailboxes @@ -157,8 +161,8 @@ impl Mailboxes { /// Return a reference to the [`Mailbox`] with the given [`Address`] pub fn find_mailbox(&self, msg_addr: &Address) -> Option<&Mailbox> { - if &self.main_mailbox.address == msg_addr { - Some(&self.main_mailbox) + if &self.primary_mailbox.address == msg_addr { + Some(&self.primary_mailbox) } else { self.additional_mailboxes .iter() @@ -200,17 +204,9 @@ impl Mailboxes { } } - /// Return all (mail + additional) [`Address`]es represented by this [`Mailboxes`] - pub fn addresses(&self) -> Vec
{ - let mut addresses = Vec::with_capacity(self.additional_mailboxes.len() + 1); - addresses.push(self.main_mailbox.address.clone()); - addresses.append(&mut self.additional_addresses()); - addresses - } - - /// Return a reference to the main [`Mailbox`] for this [`Mailboxes`] - pub fn main_mailbox(&self) -> &Mailbox { - &self.main_mailbox + /// Return a reference to the primary [`Mailbox`] for this [`Mailboxes`] + pub fn primary_mailbox(&self) -> &Mailbox { + &self.primary_mailbox } /// Return a reference to the additional [`Mailbox`]es for this [`Mailboxes`] diff --git a/implementations/rust/ockam/ockam_core/src/routing/message/local_message.rs b/implementations/rust/ockam/ockam_core/src/routing/message/local_message.rs index d387a74c589..a37c3c97f0e 100644 --- a/implementations/rust/ockam/ockam_core/src/routing/message/local_message.rs +++ b/implementations/rust/ockam/ockam_core/src/routing/message/local_message.rs @@ -63,8 +63,8 @@ impl LocalMessage { } /// Return the next address on the onward route - pub fn next_on_onward_route(&self) -> Result
{ - Ok(self.onward_route.next()?.clone()) + pub fn next_on_onward_route(&self) -> Result<&Address> { + self.onward_route.next() } /// Return true if an address exists on the onward route @@ -79,25 +79,21 @@ impl LocalMessage { } /// Prepend an address on the onward route - pub fn push_front_onward_route(mut self, address: &Address) -> Self { - self.onward_route = self.onward_route.modify().prepend(address.clone()).into(); + pub fn push_front_onward_route(mut self, address: Address) -> Self { + self.onward_route = address + self.onward_route; self } /// Replace the first address on the onward route - pub fn replace_front_onward_route(self, address: &Address) -> Result { + pub fn replace_front_onward_route(self, address: Address) -> Result { Ok(self .pop_front_onward_route()? .push_front_onward_route(address)) } /// Prepend a route to the onward route - pub fn prepend_front_onward_route(mut self, route: &Route) -> Self { - self.onward_route = self - .onward_route - .modify() - .prepend_route(route.clone()) - .into(); + pub fn prepend_front_onward_route(mut self, route: Route) -> Self { + self.onward_route = route + self.onward_route; self } @@ -119,23 +115,19 @@ impl LocalMessage { } /// Prepend an address to the return route - pub fn push_front_return_route(mut self, address: &Address) -> Self { - self.return_route = self.return_route.modify().prepend(address.clone()).into(); + pub fn push_front_return_route(mut self, address: Address) -> Self { + self.return_route = address + self.return_route; self } /// Prepend a route to the return route - pub fn prepend_front_return_route(mut self, route: &Route) -> Self { - self.return_route = self - .return_route - .modify() - .prepend_route(route.clone()) - .into(); + pub fn prepend_front_return_route(mut self, route: Route) -> Self { + self.return_route = route + self.return_route; self } /// Remove the first address on the onward route and push another address on the return route - pub fn step_forward(self, address: &Address) -> Result { + pub fn step_forward(self, address: Address) -> Result { Ok(self .pop_front_onward_route()? .push_front_return_route(address)) @@ -147,7 +139,7 @@ impl LocalMessage { } /// Return a reference to the message payload - pub fn payload_ref(&self) -> &[u8] { + pub fn payload(&self) -> &[u8] { &self.payload } @@ -162,13 +154,8 @@ impl LocalMessage { self } - /// Return the message local info - pub fn local_info(&self) -> Vec { - self.local_info.clone() - } - /// Return a reference to the message local info - pub fn local_info_ref(&self) -> &[LocalInfo] { + pub fn local_info(&self) -> &[LocalInfo] { &self.local_info } diff --git a/implementations/rust/ockam/ockam_core/src/routing/message/relay_message.rs b/implementations/rust/ockam/ockam_core/src/routing/message/relay_message.rs index 4c26a4d2e58..a46c7326b0f 100644 --- a/implementations/rust/ockam/ockam_core/src/routing/message/relay_message.rs +++ b/implementations/rust/ockam/ockam_core/src/routing/message/relay_message.rs @@ -48,7 +48,7 @@ impl RelayMessage { /// Payload pub fn payload(&self) -> &[u8] { - self.local_msg.payload_ref() + self.local_msg.payload() } /// Local message diff --git a/implementations/rust/ockam/ockam_core/src/routing/route.rs b/implementations/rust/ockam/ockam_core/src/routing/route.rs index a4b8a90ce0d..1c2955fb0cb 100644 --- a/implementations/rust/ockam/ockam_core/src/routing/route.rs +++ b/implementations/rust/ockam/ockam_core/src/routing/route.rs @@ -3,6 +3,7 @@ use crate::{ Address, Result, RouteError, TransportType, }; use core::fmt::{self, Display}; +use core::ops::{Add, AddAssign}; use minicbor::{CborLen, Decode, Encode}; use serde::{Deserialize, Serialize}; @@ -14,6 +15,50 @@ pub struct Route { #[n(0)] inner: VecDeque
, } +impl AddAssign for Route { + fn add_assign(&mut self, mut rhs: Self) { + self.inner.append(&mut rhs.inner); + } +} + +impl Add for Route { + type Output = Route; + + fn add(mut self, rhs: Self) -> Self::Output { + self += rhs; + self + } +} + +impl Add for Address { + type Output = Route; + + fn add(self, rhs: Route) -> Self::Output { + rhs.modify().prepend(self).build() + } +} + +impl AddAssign for Route +where + T: Into
, +{ + fn add_assign(&mut self, rhs: T) { + self.inner.push_back(rhs.into()); + } +} + +impl Add for Route +where + T: Into
, +{ + type Output = Route; + + fn add(mut self, rhs: T) -> Self::Output { + self += rhs; + self + } +} + impl Route { /// Create an empty [`RouteBuilder`]. /// @@ -425,11 +470,8 @@ impl RouteBuilder { /// .into(); /// ``` /// - pub fn append_route(mut self, route: Route) -> Self { - route - .inner - .into_iter() - .for_each(|addr| self.inner.push_back(addr)); + pub fn append_route(mut self, route: impl Into) -> Self { + self.inner.append(&mut route.into().inner); self } diff --git a/implementations/rust/ockam/ockam_identity/src/credentials/retriever/remote_retriever/remote_retriever_creator.rs b/implementations/rust/ockam/ockam_identity/src/credentials/retriever/remote_retriever/remote_retriever_creator.rs index c90c2a7b7ad..d20be1da7e7 100644 --- a/implementations/rust/ockam/ockam_identity/src/credentials/retriever/remote_retriever/remote_retriever_creator.rs +++ b/implementations/rust/ockam/ockam_identity/src/credentials/retriever/remote_retriever/remote_retriever_creator.rs @@ -99,12 +99,12 @@ impl CredentialRetrieverCreator for RemoteCredentialRetrieverCreator { "Creating new RemoteCredentialRetriever for: {}, authority: {}", subject, self.info.issuer ); - let mailboxes = Mailboxes::main( + let mailboxes = Mailboxes::primary( Address::random_tagged("RemoteCredentialRetriever"), Arc::new(DenyAll), Arc::new(AllowAll), ); - let ctx = self.ctx.new_detached_with_mailboxes(mailboxes).await?; + let ctx = self.ctx.new_detached_with_mailboxes(mailboxes)?; let retriever = RemoteCredentialRetriever::new( ctx, self.transport.clone(), diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channel/decryptor.rs b/implementations/rust/ockam/ockam_identity/src/secure_channel/decryptor.rs index d37ce85fbac..82984807479 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channel/decryptor.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channel/decryptor.rs @@ -1,6 +1,6 @@ use core::sync::atomic::Ordering; use ockam_core::compat::sync::Arc; -use ockam_core::{route, Any, Result, Route, Routed, SecureChannelLocalInfo}; +use ockam_core::{Any, Result, Route, Routed, SecureChannelLocalInfo}; use ockam_core::{Decodable, LocalMessage}; use ockam_node::Context; @@ -107,19 +107,14 @@ impl DecryptorHandler { let mut remote_route = self.shared_state.remote_route.write().unwrap(); // Only overwrite if we know that's the latest address if remote_route.last_nonce < nonce { - let their_decryptor_address = remote_route.route.recipient()?; - remote_route.route = - route![encrypted_msg_return_route, their_decryptor_address.clone()]; + let their_decryptor_address = remote_route.route.recipient()?.clone(); + remote_route.route = encrypted_msg_return_route + their_decryptor_address; remote_route.last_nonce = nonce; } } // Add encryptor hop in the return_route (instead of our address) - let return_route = msg - .return_route - .modify() - .prepend(self.addresses.encryptor.clone()) - .into(); + let return_route = self.addresses.encryptor.clone() + msg.return_route; // Mark message LocalInfo with IdentitySecureChannelLocalInfo, // replacing any pre-existing entries @@ -147,13 +142,15 @@ impl DecryptorHandler { } } - async fn handle_close(&mut self, ctx: &mut Context) -> Result<()> { + fn handle_close(&mut self, ctx: &mut Context) -> Result<()> { // Prevent sending another Close message self.shared_state .should_send_close .store(false, Ordering::Relaxed); // Should be enough to stop the encryptor, since it will stop the decryptor - ctx.stop_worker(self.addresses.encryptor.clone()).await + ctx.stop_address(&self.addresses.encryptor)?; + + Ok(()) } async fn handle_refresh_credentials( @@ -215,7 +212,7 @@ impl DecryptorHandler { SecureChannelMessage::RefreshCredentials(decrypted_msg) => { self.handle_refresh_credentials(ctx, decrypted_msg).await? } - SecureChannelMessage::Close => self.handle_close(ctx).await?, + SecureChannelMessage::Close => self.handle_close(ctx)?, }; Ok(()) diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channel/encryptor_worker.rs b/implementations/rust/ockam/ockam_identity/src/secure_channel/encryptor_worker.rs index b958fdac970..61b98cb3722 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channel/encryptor_worker.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channel/encryptor_worker.rs @@ -108,9 +108,9 @@ impl EncryptorWorker { // If encryption failed, that means we have some internal error, // and we may be in an invalid state, it's better to stop the Worker Err(err) => { - let address = self.addresses.encryptor.clone(); + let address = &self.addresses.encryptor; error!("Error while encrypting: {err} at: {address}"); - ctx.stop_worker(address).await?; + ctx.stop_address(address)?; Err(err) } } @@ -162,7 +162,7 @@ impl EncryptorWorker { .await?; if should_stop { - ctx.stop_worker(self.addresses.encryptor.clone()).await?; + ctx.stop_address(&self.addresses.encryptor)?; } Ok(()) @@ -334,7 +334,7 @@ impl Worker for EncryptorWorker { Ok(()) } - #[instrument(skip_all, name = "EncryptorWorker::handle_message", fields(worker = % ctx.address()))] + #[instrument(skip_all, name = "EncryptorWorker::handle_message", fields(worker = % ctx.primary_address()))] async fn handle_message( &mut self, ctx: &mut Self::Context, @@ -367,9 +367,7 @@ impl Worker for EncryptorWorker { credential_retriever.unsubscribe(&self.addresses.encryptor_internal)?; } - let _ = context - .stop_worker(self.addresses.decryptor_internal.clone()) - .await; + let _ = context.stop_address(&self.addresses.decryptor_internal); if self.shared_state.should_send_close.load(Ordering::Relaxed) { let _ = self.send_close_channel(context).await; } diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channel/handshake/handshake_worker.rs b/implementations/rust/ockam/ockam_identity/src/secure_channel/handshake/handshake_worker.rs index 40c8b3383a2..8d2223fea75 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channel/handshake/handshake_worker.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channel/handshake/handshake_worker.rs @@ -4,8 +4,8 @@ use ockam_core::compat::boxed::Box; use ockam_core::compat::sync::{Arc, RwLock}; use ockam_core::errcode::{Kind, Origin}; use ockam_core::{ - AllowAll, Any, DenyAll, Error, Mailbox, Mailboxes, NeutralMessage, OutgoingAccessControl, - Route, Routed, SecureChannelMetadata, + AddressMetadata, AllowAll, Any, DenyAll, Error, Mailbox, Mailboxes, NeutralMessage, + OutgoingAccessControl, Route, Routed, SecureChannelMetadata, }; use ockam_core::{Result, Worker}; use ockam_node::callback::CallbackSender; @@ -116,7 +116,7 @@ impl Worker for HandshakeWorker { } async fn shutdown(&mut self, context: &mut Self::Context) -> Result<()> { - let _ = context.stop_worker(self.addresses.encryptor.clone()).await; + let _ = context.stop_address(&self.addresses.encryptor); self.secure_channels .secure_channel_registry .unregister_channel(&self.addresses.encryptor); @@ -213,8 +213,7 @@ impl HandshakeWorker { &addresses, decryptor_outgoing_access_control, )) - .start(context) - .await?; + .start(context)?; debug!( "Starting SecureChannel {} at remote: {}, local: {}", @@ -351,6 +350,7 @@ impl HandshakeWorker { ) -> Mailboxes { let remote_mailbox = Mailbox::new( addresses.decryptor_remote.clone(), + None, // Doesn't matter since we check incoming messages cryptographically, // but this may be reduced to allowing only from the transport connection that was used // to create this channel initially @@ -360,11 +360,13 @@ impl HandshakeWorker { ); let internal_mailbox = Mailbox::new( addresses.decryptor_internal.clone(), + None, Arc::new(DenyAll), decryptor_outgoing_access_control, ); let api_mailbox = Mailbox::new( addresses.decryptor_api.clone(), + None, Arc::new(AllowAll), Arc::new(AllowAll), ); @@ -424,16 +426,24 @@ impl HandshakeWorker { let main_mailbox = Mailbox::new( self.addresses.encryptor.clone(), + Some(AddressMetadata { + is_terminal: true, + attributes: vec![SecureChannelMetadata::attribute( + their_identifier.clone().into(), + )], + }), Arc::new(AllowAll), Arc::new(AllowAll), ); let api_mailbox = Mailbox::new( self.addresses.encryptor_api.clone(), + None, Arc::new(AllowAll), Arc::new(AllowAll), ); let internal_mailbox = Mailbox::new( self.addresses.encryptor_internal.clone(), + None, Arc::new(AllowAll), Arc::new(DenyAll), ); @@ -443,14 +453,7 @@ impl HandshakeWorker { main_mailbox, vec![api_mailbox, internal_mailbox], )) - .terminal_with_attributes( - self.addresses.encryptor.clone(), - vec![SecureChannelMetadata::attribute( - their_identifier.clone().into(), - )], - ) - .start(context) - .await?; + .start(context)?; } self.persist( diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channel/listener.rs b/implementations/rust/ockam/ockam_identity/src/secure_channel/listener.rs index 31a9838360e..0d923f9a9bb 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channel/listener.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channel/listener.rs @@ -39,7 +39,7 @@ impl SecureChannelListenerWorker { } } - pub async fn create( + pub fn create( ctx: &Context, secure_channels: Arc, identifier: &Identifier, @@ -51,7 +51,7 @@ impl SecureChannelListenerWorker { let listener = Self::new(secure_channels.clone(), identifier.clone(), options); // FIXME: add ABAC policies for the key_exchange_only listener? - ctx.start_worker(address, listener).await?; + ctx.start_worker(address, listener)?; Ok(()) } @@ -70,7 +70,7 @@ impl Worker for SecureChannelListenerWorker { let addresses = Addresses::generate(Role::Responder); let flow_control_id = self.options.setup_flow_control_for_channel( ctx.flow_controls(), - ctx.address_ref(), + ctx.primary_address(), &addresses, ); let decryptor_outgoing_access_control = self @@ -117,7 +117,7 @@ impl Worker for SecureChannelListenerWorker { .await?; let mut local_message = message.into_local_message(); - local_message = local_message.replace_front_onward_route(&addresses.decryptor_remote)?; + local_message = local_message.replace_front_onward_route(addresses.decryptor_remote)?; ctx.forward(local_message).await } diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channel/options.rs b/implementations/rust/ockam/ockam_identity/src/secure_channel/options.rs index 9166ee4e11d..7199501cbb7 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channel/options.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channel/options.rs @@ -128,7 +128,7 @@ impl SecureChannelOptions { addresses: &Addresses, ) { flow_controls.add_producer( - addresses.decryptor_internal.clone(), + &addresses.decryptor_internal, flow_control_id, None, vec![addresses.encryptor.clone()], @@ -145,7 +145,7 @@ impl SecureChannelOptions { .map(|x| x.flow_control_id().clone()) { // Allow a sender with corresponding flow_control_id send messages to this address - flow_controls.add_consumer(addresses.decryptor_remote.clone(), &flow_control_id); + flow_controls.add_consumer(&addresses.decryptor_remote, &flow_control_id); } } @@ -281,10 +281,10 @@ impl SecureChannelListenerOptions { address: &Address, ) { for id in &self.consumer { - flow_controls.add_consumer(address.clone(), id); + flow_controls.add_consumer(address, id); } - flow_controls.add_spawner(address.clone(), &self.flow_control_id); + flow_controls.add_spawner(address, &self.flow_control_id); } pub(crate) fn setup_flow_control_for_channel( @@ -296,7 +296,7 @@ impl SecureChannelListenerOptions { // Add decryptor as consumer for the same ids as the listener, so that even if the initiator // updates the route - decryptor is still reachable for id in flow_controls.get_flow_control_ids_for_consumer(listener_address) { - flow_controls.add_consumer(addresses.decryptor_remote.clone(), &id); + flow_controls.add_consumer(&addresses.decryptor_remote, &id); } // TODO: What if we added a listener as a consumer for new FlowControlIds, should existing @@ -310,7 +310,7 @@ impl SecureChannelListenerOptions { let flow_control_id = FlowControls::generate_flow_control_id(); flow_controls.add_producer( - addresses.decryptor_internal.clone(), + &addresses.decryptor_internal, &flow_control_id, Some(&self.flow_control_id), vec![addresses.encryptor.clone()], diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channel/trust_policy/all_trust_policy.rs b/implementations/rust/ockam/ockam_identity/src/secure_channel/trust_policy/all_trust_policy.rs index 7e2bbbf836a..ef4d57c3c54 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channel/trust_policy/all_trust_policy.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channel/trust_policy/all_trust_policy.rs @@ -1,12 +1,12 @@ use ockam_core::async_trait; use ockam_core::compat::boxed::Box; -use ockam_core::{AsyncTryClone, Result}; +use ockam_core::{Result, TryClone}; use crate::secure_channel::trust_policy::{SecureChannelTrustInfo, TrustPolicy}; /// Succeeds only if both `TrustPolicy` checks succeeded -#[derive(AsyncTryClone)] -#[async_try_clone(crate = "ockam_core")] +#[derive(TryClone)] +#[try_clone(crate = "ockam_core")] pub struct AllTrustPolicy { // TODO: Extend for more than 2 policies first: F, diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channel/trust_policy/any_trust_policy.rs b/implementations/rust/ockam/ockam_identity/src/secure_channel/trust_policy/any_trust_policy.rs index 5cab27e5e9b..6822b2e7079 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channel/trust_policy/any_trust_policy.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channel/trust_policy/any_trust_policy.rs @@ -1,12 +1,12 @@ use ockam_core::async_trait; use ockam_core::compat::boxed::Box; -use ockam_core::{AsyncTryClone, Result}; +use ockam_core::{Result, TryClone}; use crate::secure_channel::trust_policy::{SecureChannelTrustInfo, TrustPolicy}; /// Succeeds if any or both `TrustPolicy` checks succeeded -#[derive(AsyncTryClone)] -#[async_try_clone(crate = "ockam_core")] +#[derive(TryClone)] +#[try_clone(crate = "ockam_core")] pub struct AnyTrustPolicy { // TODO: Extend for more than 2 policies first: F, diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channels/common.rs b/implementations/rust/ockam/ockam_identity/src/secure_channels/common.rs index 5171ff0acc4..fab83ed28b6 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channels/common.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channels/common.rs @@ -5,7 +5,7 @@ use core::fmt::Formatter; use minicbor::{CborLen, Decode, Encode}; use ockam_core::compat::sync::{Arc, RwLock}; use ockam_core::flow_control::{FlowControlId, FlowControls}; -use ockam_core::{route, Address, Result, Route}; +use ockam_core::{Address, Result, Route}; use serde::Serialize; /// Result of [`super::SecureChannels::create_secure_channel()`] call. @@ -25,6 +25,12 @@ impl From for Address { } } +impl AsRef
for SecureChannel { + fn as_ref(&self) -> &Address { + &self.addresses.encryptor + } +} + impl fmt::Display for SecureChannel { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( @@ -89,8 +95,8 @@ impl SecureChannel { let old_route = remote_route.clone(); - let their_decryptor_address = old_route.route.recipient()?; - let new_route = route![new_route, their_decryptor_address.clone()]; + let their_decryptor_address = old_route.route.recipient()?.clone(); + let new_route = new_route + their_decryptor_address; remote_route.route = new_route; diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channels/secure_channels.rs b/implementations/rust/ockam/ockam_identity/src/secure_channels/secure_channels.rs index 9546970d2b2..afad754c370 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channels/secure_channels.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channels/secure_channels.rs @@ -88,7 +88,7 @@ impl SecureChannels { impl SecureChannels { /// Spawns a SecureChannel listener at given `Address` with given [`SecureChannelListenerOptions`] - pub async fn create_secure_channel_listener( + pub fn create_secure_channel_listener( &self, ctx: &Context, identifier: &Identifier, @@ -106,8 +106,7 @@ impl SecureChannels { identifier, address.clone(), options, - ) - .await?; + )?; Ok(SecureChannelListener::new( address, @@ -263,8 +262,7 @@ impl SecureChannels { WorkerBuilder::new(decryptor_worker) .with_address(addresses.decryptor_api.clone()) // We only need API address here - .start(ctx) - .await?; + .start(ctx)?; let sc = SecureChannel::new( ctx.flow_controls().clone(), @@ -292,7 +290,7 @@ impl SecureChannels { } /// Stop a SecureChannel given an encryptor address - pub async fn stop_secure_channel(&self, ctx: &Context, channel: &Address) -> Result<()> { - ctx.stop_worker(channel.clone()).await + pub fn stop_secure_channel(&self, ctx: &Context, channel: &Address) -> Result<()> { + ctx.stop_address(channel) } } diff --git a/implementations/rust/ockam/ockam_identity/src/secure_channels/secure_client.rs b/implementations/rust/ockam/ockam_identity/src/secure_channels/secure_client.rs index 3516bff31dd..1b75185c70f 100644 --- a/implementations/rust/ockam/ockam_identity/src/secure_channels/secure_client.rs +++ b/implementations/rust/ockam/ockam_identity/src/secure_channels/secure_client.rs @@ -229,10 +229,9 @@ impl SecureClient { let response = client.request(ctx, req).await; let _ = self .secure_channels - .stop_secure_channel(ctx, secure_channel.encryptor_address()) - .await; + .stop_secure_channel(ctx, secure_channel.encryptor_address()); if let Some(transport_address) = transport_address { - let _ = self.transport.disconnect(transport_address).await; + let _ = self.transport.disconnect(&transport_address); } // we delay the unwrapping of the response to make sure that the secure channel is // properly stopped first @@ -274,10 +273,9 @@ impl SecureClient { let (secure_channel, transport_address) = self.create_secure_channel(ctx).await?; let _ = self .secure_channels - .stop_secure_channel(ctx, secure_channel.encryptor_address()) - .await; + .stop_secure_channel(ctx, secure_channel.encryptor_address()); if let Some(transport_address) = transport_address { - let _ = self.transport.disconnect(transport_address).await; + let _ = self.transport.disconnect(&transport_address); } Ok(()) diff --git a/implementations/rust/ockam/ockam_identity/tests/channel.rs b/implementations/rust/ockam/ockam_identity/tests/channel.rs index cc08e8af09f..07d6f36983d 100644 --- a/implementations/rust/ockam/ockam_identity/tests/channel.rs +++ b/implementations/rust/ockam/ockam_identity/tests/channel.rs @@ -31,29 +31,26 @@ async fn test_channel(ctx: &mut Context) -> Result<()> { let bob_trust_policy = TrustIdentifierPolicy::new(alice.clone()); let bob_options = SecureChannelListenerOptions::new().with_trust_policy(bob_trust_policy); - let bob_listener = secure_channels - .create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options) - .await?; + let bob_listener = + secure_channels.create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options)?; let alice_options = SecureChannelOptions::new().with_trust_policy(alice_trust_policy); let alice_channel = secure_channels .create_secure_channel(ctx, &alice, route!["bob_listener"], alice_options) .await?; - let mut child_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "child", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut child_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "child", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; ctx.flow_controls() - .add_consumer("child", bob_listener.flow_control_id()); + .add_consumer(&"child".into(), bob_listener.flow_control_id()); child_ctx .send( - route![alice_channel.clone(), child_ctx.address()], + route![alice_channel.clone(), child_ctx.primary_address().clone()], "Hello, Bob!".to_string(), ) .await?; @@ -67,7 +64,7 @@ async fn test_channel(ctx: &mut Context) -> Result<()> { assert_eq!("Hello, Bob!", msg.into_body()?); ctx.flow_controls() - .add_consumer("child", alice_channel.flow_control_id()); + .add_consumer(&"child".into(), alice_channel.flow_control_id()); child_ctx .send(return_route, "Hello, Alice!".to_string()) @@ -121,16 +118,14 @@ async fn test_channel_send_credentials(context: &mut Context) -> Result<()> { ) .await?; - secure_channels - .create_secure_channel_listener( - context, - &bob, - "bob_listener", - SecureChannelListenerOptions::new() - .with_authority(authority.clone()) - .with_credential(bob_credential_2)?, - ) - .await?; + secure_channels.create_secure_channel_listener( + context, + &bob, + "bob_listener", + SecureChannelListenerOptions::new() + .with_authority(authority.clone()) + .with_credential(bob_credential_2)?, + )?; let _alice_credential_1st = secure_channels .identities() @@ -227,14 +222,12 @@ async fn test_channel_rejected_trust_policy(ctx: &mut Context) -> Result<()> { .unwrap(), ); - secure_channels - .create_secure_channel_listener( - ctx, - &bob, - "bob_listener", - SecureChannelListenerOptions::new().with_trust_policy(alice_broken_trust_policy), - ) - .await?; + secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob_listener", + SecureChannelListenerOptions::new().with_trust_policy(alice_broken_trust_policy), + )?; let alice_channel = secure_channels .create_secure_channel( @@ -245,17 +238,15 @@ async fn test_channel_rejected_trust_policy(ctx: &mut Context) -> Result<()> { ) .await?; - let mut child_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "child", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut child_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "child", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; child_ctx .send( - route![alice_channel, child_ctx.address()], + route![alice_channel, child_ctx.primary_address().clone()], "Hello, Bob!".to_string(), ) .await?; @@ -284,9 +275,7 @@ async fn test_channel_send_multiple_messages_both_directions(ctx: &mut Context) let bob_options = SecureChannelListenerOptions::new().with_trust_policy(bob_trust_policy); let sc_listener_flow_control_id = bob_options.spawner_flow_control_id(); - secure_channels - .create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options) - .await?; + secure_channels.create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options)?; let alice_options = SecureChannelOptions::new().with_trust_policy(alice_trust_policy); let sc_flow_control_id = alice_options.producer_flow_control_id(); @@ -294,22 +283,20 @@ async fn test_channel_send_multiple_messages_both_directions(ctx: &mut Context) .create_secure_channel(ctx, &alice, route!["bob_listener"], alice_options) .await?; - let mut child_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "child", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut child_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "child", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; for n in 0..50 { child_ctx .flow_controls() - .add_consumer(child_ctx.address(), &sc_listener_flow_control_id); + .add_consumer(child_ctx.primary_address(), &sc_listener_flow_control_id); let payload = format!("Hello, Bob! {}", n); child_ctx .send( - route![alice_channel.clone(), child_ctx.address()], + route![alice_channel.clone(), child_ctx.primary_address().clone()], payload.clone(), ) .await?; @@ -320,7 +307,7 @@ async fn test_channel_send_multiple_messages_both_directions(ctx: &mut Context) child_ctx .flow_controls() - .add_consumer(child_ctx.address(), &sc_flow_control_id); + .add_consumer(child_ctx.primary_address(), &sc_flow_control_id); let payload = format!("Hello, Alice! {}", n); child_ctx.send(return_route, payload.clone()).await?; @@ -338,14 +325,12 @@ async fn test_channel_registry(ctx: &mut Context) -> Result<()> { let alice = identities_creation.create_identity().await?; let bob = identities_creation.create_identity().await?; - let bob_listener = secure_channels - .create_secure_channel_listener( - ctx, - &bob, - "bob_listener", - SecureChannelListenerOptions::new(), - ) - .await?; + let bob_listener = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob_listener", + SecureChannelListenerOptions::new(), + )?; let alice_channel = secure_channels .create_secure_channel( @@ -365,16 +350,14 @@ async fn test_channel_registry(ctx: &mut Context) -> Result<()> { assert_eq!(alice_channel_data.my_id(), &alice); assert_eq!(alice_channel_data.their_id(), &bob); - let mut bob_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "bob", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut bob_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "bob", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; ctx.flow_controls() - .add_consumer("bob", bob_listener.flow_control_id()); + .add_consumer(&"bob".into(), bob_listener.flow_control_id()); ctx.send( route![alice_channel.clone(), "bob"], @@ -409,14 +392,12 @@ async fn test_channel_api(ctx: &mut Context) -> Result<()> { let alice = identities_creation.create_identity().await?; let bob = identities_creation.create_identity().await?; - let bob_listener = secure_channels - .create_secure_channel_listener( - ctx, - &bob, - "bob_listener", - SecureChannelListenerOptions::new(), - ) - .await?; + let bob_listener = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob_listener", + SecureChannelListenerOptions::new(), + )?; let alice_channel = secure_channels .create_secure_channel( @@ -427,16 +408,14 @@ async fn test_channel_api(ctx: &mut Context) -> Result<()> { ) .await?; - let mut bob_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "bob", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut bob_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "bob", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; ctx.flow_controls() - .add_consumer("bob", bob_listener.flow_control_id()); + .add_consumer(&"bob".into(), bob_listener.flow_control_id()); ctx.send( route![alice_channel.clone(), "bob"], @@ -524,9 +503,8 @@ async fn test_tunneled_secure_channel_works(ctx: &mut Context) -> Result<()> { let bob_options = SecureChannelListenerOptions::new().with_trust_policy(bob_trust_policy.clone()); - let bob_listener = secure_channels - .create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options) - .await?; + let bob_listener = + secure_channels.create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options)?; let alice_channel = secure_channels .create_secure_channel( @@ -540,9 +518,12 @@ async fn test_tunneled_secure_channel_works(ctx: &mut Context) -> Result<()> { let bob_options_2 = SecureChannelListenerOptions::new() .as_consumer(bob_listener.flow_control_id()) .with_trust_policy(bob_trust_policy); - let bob_listener2 = secure_channels - .create_secure_channel_listener(ctx, &bob, "bob_another_listener", bob_options_2) - .await?; + let bob_listener2 = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob_another_listener", + bob_options_2, + )?; let alice_options2 = SecureChannelOptions::new().with_trust_policy(alice_trust_policy); let alice_another_channel = secure_channels @@ -554,20 +535,21 @@ async fn test_tunneled_secure_channel_works(ctx: &mut Context) -> Result<()> { ) .await?; - let mut child_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "child", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut child_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "child", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; ctx.flow_controls() - .add_consumer("child", bob_listener2.flow_control_id()); + .add_consumer(&"child".into(), bob_listener2.flow_control_id()); child_ctx .send( - route![alice_another_channel.clone(), child_ctx.address()], + route![ + alice_another_channel.clone(), + child_ctx.primary_address().clone() + ], "Hello, Bob!".to_string(), ) .await?; @@ -576,7 +558,7 @@ async fn test_tunneled_secure_channel_works(ctx: &mut Context) -> Result<()> { assert_eq!("Hello, Bob!", msg.into_body()?); ctx.flow_controls() - .add_consumer("child", alice_another_channel.flow_control_id()); + .add_consumer(&"child".into(), alice_another_channel.flow_control_id()); child_ctx .send(return_route, "Hello, Alice!".to_string()) @@ -602,9 +584,8 @@ async fn test_double_tunneled_secure_channel_works(ctx: &mut Context) -> Result< let bob_options = SecureChannelListenerOptions::new().with_trust_policy(bob_trust_policy.clone()); - let bob_listener = secure_channels - .create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options) - .await?; + let bob_listener = + secure_channels.create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options)?; let alice_channel = secure_channels .create_secure_channel( @@ -618,9 +599,12 @@ async fn test_double_tunneled_secure_channel_works(ctx: &mut Context) -> Result< let bob_options2 = SecureChannelListenerOptions::new() .as_consumer(bob_listener.flow_control_id()) .with_trust_policy(bob_trust_policy.clone()); - let bob_listener2 = secure_channels - .create_secure_channel_listener(ctx, &bob, "bob_another_listener", bob_options2) - .await?; + let bob_listener2 = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob_another_listener", + bob_options2, + )?; let alice_another_channel = secure_channels .create_secure_channel( @@ -634,9 +618,12 @@ async fn test_double_tunneled_secure_channel_works(ctx: &mut Context) -> Result< let bob_options3 = SecureChannelListenerOptions::new() .as_consumer(bob_listener2.flow_control_id()) .with_trust_policy(bob_trust_policy); - let bob_listener3 = secure_channels - .create_secure_channel_listener(ctx, &bob, "bob_yet_another_listener", bob_options3) - .await?; + let bob_listener3 = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob_yet_another_listener", + bob_options3, + )?; let alice_options3 = SecureChannelOptions::new().with_trust_policy(alice_trust_policy.clone()); let alice_yet_another_channel = secure_channels @@ -648,20 +635,21 @@ async fn test_double_tunneled_secure_channel_works(ctx: &mut Context) -> Result< ) .await?; - let mut child_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "child", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut child_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "child", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; ctx.flow_controls() - .add_consumer("child", bob_listener3.flow_control_id()); + .add_consumer(&"child".into(), bob_listener3.flow_control_id()); child_ctx .send( - route![alice_yet_another_channel.clone(), child_ctx.address()], + route![ + alice_yet_another_channel.clone(), + child_ctx.primary_address().clone() + ], "Hello, Bob!".to_string(), ) .await?; @@ -670,7 +658,7 @@ async fn test_double_tunneled_secure_channel_works(ctx: &mut Context) -> Result< assert_eq!("Hello, Bob!", msg.into_body()?); ctx.flow_controls() - .add_consumer("child", alice_yet_another_channel.flow_control_id()); + .add_consumer(&"child".into(), alice_yet_another_channel.flow_control_id()); child_ctx .send(return_route, "Hello, Alice!".to_string()) @@ -707,12 +695,10 @@ async fn test_many_times_tunneled_secure_channel_works(ctx: &mut Context) -> Res None => options, }; sc_listener_flow_control_id = Some(options.spawner_flow_control_id()); - secure_channels - .create_secure_channel_listener(ctx, &bob, i.to_string(), options) - .await?; + secure_channels.create_secure_channel_listener(ctx, &bob, i.to_string(), options)?; let mut route = route![i.to_string()]; if let Some(last_channel) = channels.last() { - route = route.modify().prepend(last_channel.clone()).into(); + route = last_channel.clone() + route; } let options = SecureChannelOptions::new().with_trust_policy(alice_trust_policy.clone()); @@ -724,20 +710,21 @@ async fn test_many_times_tunneled_secure_channel_works(ctx: &mut Context) -> Res channels.push(alice_channel.encryptor_address().clone()); } - let mut child_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "child", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut child_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "child", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; ctx.flow_controls() - .add_consumer("child", &sc_listener_flow_control_id.unwrap()); + .add_consumer(&"child".into(), &sc_listener_flow_control_id.unwrap()); child_ctx .send( - route![channels.last().unwrap().clone(), child_ctx.address()], + route![ + channels.last().unwrap().clone(), + child_ctx.primary_address().clone() + ], "Hello, Bob!".to_string(), ) .await?; @@ -746,7 +733,7 @@ async fn test_many_times_tunneled_secure_channel_works(ctx: &mut Context) -> Res assert_eq!("Hello, Bob!", msg.into_body()?); ctx.flow_controls() - .add_consumer("child", &sc_flow_control_id.unwrap()); + .add_consumer(&"child".into(), &sc_flow_control_id.unwrap()); child_ctx .send(return_route, "Hello, Alice!".to_string()) @@ -797,12 +784,14 @@ async fn access_control__known_participant__should_pass_messages(ctx: &mut Conte .with_address("receiver") .with_incoming_access_control(access_control) .with_outgoing_access_control(DenyAll) - .start(ctx) - .await?; + .start(ctx)?; - let bob_listener = secure_channels - .create_secure_channel_listener(ctx, &bob, "listener", SecureChannelListenerOptions::new()) - .await?; + let bob_listener = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "listener", + SecureChannelListenerOptions::new(), + )?; let alice_channel = secure_channels .create_secure_channel( @@ -814,7 +803,7 @@ async fn access_control__known_participant__should_pass_messages(ctx: &mut Conte .await?; ctx.flow_controls() - .add_consumer("receiver", bob_listener.flow_control_id()); + .add_consumer(&"receiver".into(), bob_listener.flow_control_id()); ctx.send(route![alice_channel, "receiver"], "Hello, Bob!".to_string()) .await?; @@ -847,12 +836,14 @@ async fn access_control__unknown_participant__should_not_pass_messages( .with_address("receiver") .with_incoming_access_control(access_control) .with_outgoing_access_control(DenyAll) - .start(ctx) - .await?; + .start(ctx)?; - let bob_listener = secure_channels - .create_secure_channel_listener(ctx, &bob, "listener", SecureChannelListenerOptions::new()) - .await?; + let bob_listener = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "listener", + SecureChannelListenerOptions::new(), + )?; let alice_channel = secure_channels .create_secure_channel( @@ -864,7 +855,7 @@ async fn access_control__unknown_participant__should_not_pass_messages( .await?; ctx.flow_controls() - .add_consumer("receiver", bob_listener.flow_control_id()); + .add_consumer(&"receiver".into(), bob_listener.flow_control_id()); ctx.send(route![alice_channel, "receiver"], "Hello, Bob!".to_string()) .await?; @@ -893,8 +884,7 @@ async fn access_control__no_secure_channel__should_not_pass_messages( .with_address("receiver") .with_incoming_access_control(access_control) .with_outgoing_access_control(DenyAll) - .start(ctx) - .await?; + .start(ctx)?; ctx.send(route!["receiver"], "Hello, Bob!".to_string()) .await?; @@ -976,14 +966,12 @@ async fn test_channel_delete_ephemeral_keys(ctx: &mut Context) -> Result<()> { .create_secure_channel_purpose_key(&bob) .await?; - secure_channels_bob - .create_secure_channel_listener( - ctx, - &bob, - "bob_listener", - SecureChannelListenerOptions::new(), - ) - .await?; + secure_channels_bob.create_secure_channel_listener( + ctx, + &bob, + "bob_listener", + SecureChannelListenerOptions::new(), + )?; assert_eq!(bob_identity_vault.number_of_keys().await?, 1); assert_eq!(bob_sc_vault.number_of_ephemeral_aead_secrets(), 0); assert_eq!(bob_sc_vault.number_of_ephemeral_buffer_secrets(), 0); @@ -1013,7 +1001,23 @@ async fn test_channel_delete_ephemeral_keys(ctx: &mut Context) -> Result<()> { assert_eq!(bob_sc_vault.number_of_ephemeral_x25519_secrets(), 0); assert_eq!(bob_sc_vault.number_of_static_x25519_secrets().await?, 1); - ctx.stop().await?; + let alice_sc = secure_channels_alice + .secure_channel_registry() + .get_channel_list() + .first() + .unwrap() + .clone(); + secure_channels_alice.stop_secure_channel(ctx, alice_sc.encryptor_messaging_address())?; + + let bob_sc = secure_channels_bob + .secure_channel_registry() + .get_channel_list() + .first() + .unwrap() + .clone(); + secure_channels_bob.stop_secure_channel(ctx, bob_sc.encryptor_messaging_address())?; + + ctx.sleep(Duration::from_millis(250)).await; // when the channel is closed only purpose key should be left assert_eq!(alice_identity_vault.number_of_keys().await?, 1); @@ -1042,14 +1046,12 @@ async fn should_stop_encryptor__and__decryptor__in__secure_channel( let alice = identities_creation.create_identity().await?; let bob = identities_creation.create_identity().await?; - let _bob_listener = secure_channels - .create_secure_channel_listener( - ctx, - &bob, - "bob_listener", - SecureChannelListenerOptions::new(), - ) - .await?; + let _bob_listener = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob_listener", + SecureChannelListenerOptions::new(), + )?; secure_channels .create_secure_channel( @@ -1069,9 +1071,7 @@ async fn should_stop_encryptor__and__decryptor__in__secure_channel( let channel2 = sc_list[1].clone(); // This will stop both ends of the channel - secure_channels - .stop_secure_channel(ctx, channel1.encryptor_messaging_address()) - .await?; + secure_channels.stop_secure_channel(ctx, channel1.encryptor_messaging_address())?; ctx.sleep(Duration::from_millis(250)).await; @@ -1083,7 +1083,7 @@ async fn should_stop_encryptor__and__decryptor__in__secure_channel( 0 ); - let workers = ctx.list_workers(); + let workers = ctx.list_workers()?; assert!(!workers.contains(channel1.decryptor_messaging_address())); assert!(!workers.contains(channel1.encryptor_messaging_address())); assert!(!workers.contains(channel2.decryptor_messaging_address())); @@ -1101,14 +1101,12 @@ async fn address_metadata__encryptor__should_be_terminal(ctx: &mut Context) -> R let alice = identities_creation.create_identity().await?; let bob = identities_creation.create_identity().await?; - let _bob_listener = secure_channels - .create_secure_channel_listener( - ctx, - &bob, - "bob_listener", - SecureChannelListenerOptions::new(), - ) - .await?; + let _bob_listener = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob_listener", + SecureChannelListenerOptions::new(), + )?; let sc = secure_channels .create_secure_channel( @@ -1119,17 +1117,15 @@ async fn address_metadata__encryptor__should_be_terminal(ctx: &mut Context) -> R ) .await?; - let meta = ctx - .find_terminal_address(route!["app", sc.clone(), "test"]) - .await? - .unwrap(); + let route = route!["app", sc.clone(), "test"]; + let (address, meta) = ctx.find_terminal_address(route.iter())?.unwrap(); - assert_eq!(meta.address, sc.into()); + assert_eq!(address, &sc.into()); assert_eq!( - meta.metadata.attributes, + meta.attributes, vec![(SECURE_CHANNEL_IDENTIFIER.to_string(), hex::encode(bob.0))] ); - assert!(meta.metadata.is_terminal); + assert!(meta.is_terminal); Ok(()) } diff --git a/implementations/rust/ockam/ockam_identity/tests/ciphertext_message_flow_auth.rs b/implementations/rust/ockam/ockam_identity/tests/ciphertext_message_flow_auth.rs index 7b4d5282a5b..56c69f8aede 100644 --- a/implementations/rust/ockam/ockam_identity/tests/ciphertext_message_flow_auth.rs +++ b/implementations/rust/ockam/ockam_identity/tests/ciphertext_message_flow_auth.rs @@ -15,12 +15,12 @@ mod common; // Bob: TCP listener + Secure Channel listener #[ockam_macros::test] async fn test1(ctx: &mut Context) -> Result<()> { - let tcp_bob = TcpTransport::create(ctx).await?; + let tcp_bob = TcpTransport::create(ctx)?; let listener = tcp_bob .listen("127.0.0.1:0", TcpListenerOptions::new()) .await?; - let tcp_alice = TcpTransport::create(ctx).await?; + let tcp_alice = TcpTransport::create(ctx)?; let connection_to_bob = tcp_alice .connect(listener.socket_string(), TcpConnectionOptions::new()) .await?; @@ -66,13 +66,13 @@ async fn test1(ctx: &mut Context) -> Result<()> { // Bob: TCP listener + Secure Channel #[ockam_macros::test] async fn test2(ctx: &mut Context) -> Result<()> { - let tcp_bob = TcpTransport::create(ctx).await?; + let tcp_bob = TcpTransport::create(ctx)?; let listener = { let options = TcpListenerOptions::new(); tcp_bob.listen("127.0.0.1:0", options).await? }; - let tcp_alice = TcpTransport::create(ctx).await?; + let tcp_alice = TcpTransport::create(ctx)?; let alice_tcp_options = TcpConnectionOptions::new(); let alice_flow_control_id = alice_tcp_options.flow_control_id(); let connection_to_bob = tcp_alice diff --git a/implementations/rust/ockam/ockam_identity/tests/common/message_flow_auth.rs b/implementations/rust/ockam/ockam_identity/tests/common/message_flow_auth.rs index 12bb645d774..45f819a4c26 100644 --- a/implementations/rust/ockam/ockam_identity/tests/common/message_flow_auth.rs +++ b/implementations/rust/ockam/ockam_identity/tests/common/message_flow_auth.rs @@ -20,13 +20,11 @@ pub async fn message_should_not_pass(ctx: &Context, address: &Address) -> Result async fn check_message_flow(ctx: &Context, route: Route, should_pass: bool) -> Result<()> { let address = Address::random_local(); - let mut receiving_ctx = ctx - .new_detached(address.clone(), AllowAll, AllowAll) - .await?; + let mut receiving_ctx = ctx.new_detached(address.clone(), AllowAll, AllowAll)?; let msg: [u8; 4] = random(); let msg = hex::encode(msg); - ctx.send(route![route, address], msg.clone()).await?; + ctx.send(route + address, msg.clone()).await?; if should_pass { let msg_received = receiving_ctx.receive::().await?.into_body()?; @@ -66,7 +64,7 @@ async fn check_message_flow_with_ctx( let msg: [u8; 4] = random(); let msg = hex::encode(msg); ctx.send( - route![address.clone(), receiving_ctx.address()], + route![address.clone(), receiving_ctx.primary_address().clone()], msg.clone(), ) .await?; @@ -111,9 +109,8 @@ pub async fn create_secure_channel_listener( let identifier = identities_creation.create_identity().await?; let options = SecureChannelListenerOptions::new().as_consumer(flow_control_id); - let listener = secure_channels - .create_secure_channel_listener(ctx, &identifier, "listener", options) - .await?; + let listener = + secure_channels.create_secure_channel_listener(ctx, &identifier, "listener", options)?; let info = SecureChannelListenerInfo { secure_channels, diff --git a/implementations/rust/ockam/ockam_identity/tests/credentials.rs b/implementations/rust/ockam/ockam_identity/tests/credentials.rs index 0cdad3168f7..330218410ec 100644 --- a/implementations/rust/ockam/ockam_identity/tests/credentials.rs +++ b/implementations/rust/ockam/ockam_identity/tests/credentials.rs @@ -38,14 +38,12 @@ async fn full_flow_oneway(ctx: &mut Context) -> Result<()> { ) .await?; - secure_channels - .create_secure_channel_listener( - ctx, - &server, - "listener", - SecureChannelListenerOptions::new().with_authority(authority.clone()), - ) - .await?; + secure_channels.create_secure_channel_listener( + ctx, + &server, + "listener", + SecureChannelListenerOptions::new().with_authority(authority.clone()), + )?; secure_channels .create_secure_channel( @@ -96,16 +94,14 @@ async fn full_flow_twoway(ctx: &mut Context) -> Result<()> { ) .await?; - secure_channels - .create_secure_channel_listener( - ctx, - &client1, - "listener", - SecureChannelListenerOptions::new() - .with_authority(authority.clone()) - .with_credential(credential)?, - ) - .await?; + secure_channels.create_secure_channel_listener( + ctx, + &client1, + "listener", + SecureChannelListenerOptions::new() + .with_authority(authority.clone()) + .with_credential(credential)?, + )?; let credential = credentials .credentials_creation() @@ -174,9 +170,8 @@ async fn access_control(ctx: &mut Context) -> Result<()> { let client2 = identities_creation.create_identity().await?; let options = SecureChannelListenerOptions::new().with_authority(authority.clone()); - let listener = secure_channels - .create_secure_channel_listener(ctx, &server, "listener", options) - .await?; + let listener = + secure_channels.create_secure_channel_listener(ctx, &server, "listener", options)?; let credential1 = credentials .credentials_creation() @@ -220,14 +215,13 @@ async fn access_control(ctx: &mut Context) -> Result<()> { CredentialAccessControl::new(&required_attributes, authority, identities_attributes); ctx.flow_controls() - .add_consumer("counter", listener.flow_control_id()); + .add_consumer(&"counter".into(), listener.flow_control_id()); WorkerBuilder::new(worker) .with_address("counter") .with_incoming_access_control(access_control) .with_outgoing_access_control(DenyAll) - .start(ctx) - .await?; + .start(ctx)?; ctx.sleep(Duration::from_millis(100)).await; assert_eq!(counter.load(Ordering::Relaxed), 0); @@ -269,14 +263,12 @@ async fn missing_authority__handshake_should_succeed(ctx: &mut Context) -> Resul ) .await?; - let listener = secure_channels - .create_secure_channel_listener( - ctx, - &server, - "listener", - SecureChannelListenerOptions::new(), - ) - .await?; + let listener = secure_channels.create_secure_channel_listener( + ctx, + &server, + "listener", + SecureChannelListenerOptions::new(), + )?; let sc = secure_channels .create_secure_channel( @@ -298,9 +290,9 @@ async fn missing_authority__handshake_should_succeed(ctx: &mut Context) -> Resul // However secure channel should be operational anyways - ctx.start_worker("echo", Echoer).await?; + ctx.start_worker("echo", Echoer)?; ctx.flow_controls() - .add_consumer("echo", listener.flow_control_id()); + .add_consumer(&"echo".into(), listener.flow_control_id()); let msg: String = ctx .send_and_receive(route![sc, "echo"], "Test".to_string()) @@ -336,14 +328,12 @@ async fn invalid_credential__handshake_should_succeed(ctx: &mut Context) -> Resu ) .await?; - let listener = secure_channels - .create_secure_channel_listener( - ctx, - &server, - "listener", - SecureChannelListenerOptions::new().with_authority(authority.clone()), - ) - .await?; + let listener = secure_channels.create_secure_channel_listener( + ctx, + &server, + "listener", + SecureChannelListenerOptions::new().with_authority(authority.clone()), + )?; let sc = secure_channels .create_secure_channel( @@ -371,9 +361,9 @@ async fn invalid_credential__handshake_should_succeed(ctx: &mut Context) -> Resu // However secure channel should be operational anyways - ctx.start_worker("echo", Echoer).await?; + ctx.start_worker("echo", Echoer)?; ctx.flow_controls() - .add_consumer("echo", listener.flow_control_id()); + .add_consumer(&"echo".into(), listener.flow_control_id()); let msg: String = ctx .send_and_receive(route![sc, "echo"], "Test".to_string()) diff --git a/implementations/rust/ockam/ockam_identity/tests/credentials_refresh.rs b/implementations/rust/ockam/ockam_identity/tests/credentials_refresh.rs index f4e69584ea8..780dc25065b 100644 --- a/implementations/rust/ockam/ockam_identity/tests/credentials_refresh.rs +++ b/implementations/rust/ockam/ockam_identity/tests/credentials_refresh.rs @@ -3,7 +3,7 @@ use std::time::Duration; use ockam_core::api::Response; use ockam_core::compat::sync::Arc; -use ockam_core::{async_trait, Any, AsyncTryClone, Routed, SecureChannelLocalInfo, Worker}; +use ockam_core::{async_trait, Any, Routed, SecureChannelLocalInfo, TryClone, Worker}; use ockam_core::{route, Result}; use ockam_identity::models::CredentialSchemaIdentifier; use ockam_identity::secure_channels::secure_channels; @@ -210,7 +210,7 @@ async fn init( ttl: Duration, timing_options: RemoteCredentialRetrieverTimingOptions, ) -> Result { - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let client_secure_channels = secure_channels().await?; let authority_secure_channels = secure_channels().await?; @@ -252,31 +252,27 @@ async fn init( ttl, }; - ctx.start_worker("credential_issuer", issuer).await?; + ctx.start_worker("credential_issuer", issuer)?; - let listener = authority_secure_channels - .create_secure_channel_listener( - ctx, - &authority, - "authority_api", - SecureChannelListenerOptions::new(), - ) - .await?; + let listener = authority_secure_channels.create_secure_channel_listener( + ctx, + &authority, + "authority_api", + SecureChannelListenerOptions::new(), + )?; ctx.flow_controls() - .add_consumer("credential_issuer", listener.flow_control_id()); + .add_consumer(&"credential_issuer".into(), listener.flow_control_id()); - server_secure_channels - .create_secure_channel_listener( - ctx, - &server, - "server_api", - SecureChannelListenerOptions::new().with_authority(authority.clone()), - ) - .await?; + server_secure_channels.create_secure_channel_listener( + ctx, + &server, + "server_api", + SecureChannelListenerOptions::new().with_authority(authority.clone()), + )?; let retriever = Arc::new(RemoteCredentialRetrieverCreator::new_extended( - ctx.async_try_clone().await?, + ctx.try_clone()?, Arc::new(tcp), client_secure_channels.clone(), RemoteCredentialRetrieverInfo::create_for_project_member( diff --git a/implementations/rust/ockam/ockam_identity/tests/persistence.rs b/implementations/rust/ockam/ockam_identity/tests/persistence.rs index 3e859728d64..18990b20ab3 100644 --- a/implementations/rust/ockam/ockam_identity/tests/persistence.rs +++ b/implementations/rust/ockam/ockam_identity/tests/persistence.rs @@ -28,9 +28,7 @@ async fn test_key_exchange_only(ctx: &mut Context) -> ockam_core::Result<()> { .await?; let bob_options = SecureChannelListenerOptions::new().key_exchange_only(); - secure_channels_bob - .create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options) - .await?; + secure_channels_bob.create_secure_channel_listener(ctx, &bob, "bob_listener", bob_options)?; let alice_options = SecureChannelOptions::new().key_exchange_only(); let alice_channel = secure_channels_alice @@ -197,9 +195,12 @@ fn test_persistence() -> ockam_core::Result<()> { let bob_options = SecureChannelListenerOptions::new() .key_exchange_only() .persist()?; - secure_channels_bob - .create_secure_channel_listener(&ctx1, &bob, "bob_listener", bob_options) - .await?; + secure_channels_bob.create_secure_channel_listener( + &ctx1, + &bob, + "bob_listener", + bob_options, + )?; let alice_options = SecureChannelOptions::new().key_exchange_only().persist()?; let alice_channel = secure_channels_alice @@ -278,7 +279,7 @@ fn test_persistence() -> ockam_core::Result<()> { .catch_unwind() .await; - ctx1.stop().await?; + ctx1.shutdown_node().await?; data.unwrap() }) @@ -373,7 +374,7 @@ fn test_persistence() -> ockam_core::Result<()> { .catch_unwind() .await; - ctx2.stop().await?; + ctx2.shutdown_node().await?; res.unwrap() }) diff --git a/implementations/rust/ockam/ockam_identity/tests/plaintext_message_flow_auth.rs b/implementations/rust/ockam/ockam_identity/tests/plaintext_message_flow_auth.rs index 9b4008d9b2d..756b4f9c01a 100644 --- a/implementations/rust/ockam/ockam_identity/tests/plaintext_message_flow_auth.rs +++ b/implementations/rust/ockam/ockam_identity/tests/plaintext_message_flow_auth.rs @@ -28,9 +28,12 @@ async fn test1(ctx: &mut Context) -> Result<()> { .create_identity() .await?; - let bob_listener = bob_secure_channels - .create_secure_channel_listener(ctx, &bob, "listener", SecureChannelListenerOptions::new()) - .await?; + let bob_listener = bob_secure_channels.create_secure_channel_listener( + ctx, + &bob, + "listener", + SecureChannelListenerOptions::new(), + )?; let channel_to_bob = alice_secure_channels .create_secure_channel(ctx, &alice, route!["listener"], SecureChannelOptions::new()) @@ -45,16 +48,16 @@ async fn test1(ctx: &mut Context) -> Result<()> { .encryptor_messaging_address() .clone(); - let mut bob_ctx = ctx.new_detached("bob_ctx", AllowAll, AllowAll).await?; + let mut bob_ctx = ctx.new_detached("bob_ctx", AllowAll, AllowAll)?; message_should_not_pass_with_ctx(ctx, channel_to_bob.encryptor_address(), &mut bob_ctx).await?; ctx.flow_controls() - .add_consumer("bob_ctx", bob_listener.flow_control_id()); + .add_consumer(&"bob_ctx".into(), bob_listener.flow_control_id()); message_should_pass_with_ctx(ctx, channel_to_bob.encryptor_address(), &mut bob_ctx).await?; - let mut alice_ctx = ctx.new_detached("alice_ctx", AllowAll, AllowAll).await?; + let mut alice_ctx = ctx.new_detached("alice_ctx", AllowAll, AllowAll)?; message_should_not_pass_with_ctx(ctx, &channel_to_alice, &mut alice_ctx).await?; ctx.flow_controls() - .add_consumer("alice_ctx", channel_to_bob.flow_control_id()); + .add_consumer(&"alice_ctx".into(), channel_to_bob.flow_control_id()); message_should_pass_with_ctx(ctx, &channel_to_alice, &mut alice_ctx).await?; Ok(()) @@ -64,8 +67,8 @@ async fn test1(ctx: &mut Context) -> Result<()> { // Bob: TCP listener + Secure Channel listener #[ockam_macros::test] async fn test2(ctx: &mut Context) -> Result<()> { - let tcp_alice = TcpTransport::create(ctx).await?; - let tcp_bob = TcpTransport::create(ctx).await?; + let tcp_alice = TcpTransport::create(ctx)?; + let tcp_bob = TcpTransport::create(ctx)?; let listener = tcp_bob .listen("127.0.0.1:0", TcpListenerOptions::new()) @@ -100,9 +103,8 @@ async fn test2(ctx: &mut Context) -> Result<()> { .await?; let bob_options = SecureChannelListenerOptions::new().as_consumer(listener.flow_control_id()); - let bob_listener = bob_secure_channels - .create_secure_channel_listener(ctx, &bob, "listener", bob_options) - .await?; + let bob_listener = + bob_secure_channels.create_secure_channel_listener(ctx, &bob, "listener", bob_options)?; let channel_to_bob = alice_secure_channels .create_secure_channel( @@ -125,16 +127,16 @@ async fn test2(ctx: &mut Context) -> Result<()> { .encryptor_messaging_address() .clone(); - let mut bob_ctx = ctx.new_detached("bob_ctx", AllowAll, AllowAll).await?; + let mut bob_ctx = ctx.new_detached("bob_ctx", AllowAll, AllowAll)?; message_should_not_pass_with_ctx(ctx, channel_to_bob.encryptor_address(), &mut bob_ctx).await?; ctx.flow_controls() - .add_consumer("bob_ctx", bob_listener.flow_control_id()); + .add_consumer(&"bob_ctx".into(), bob_listener.flow_control_id()); message_should_pass_with_ctx(ctx, channel_to_bob.encryptor_address(), &mut bob_ctx).await?; - let mut alice_ctx = ctx.new_detached("alice_ctx", AllowAll, AllowAll).await?; + let mut alice_ctx = ctx.new_detached("alice_ctx", AllowAll, AllowAll)?; message_should_not_pass_with_ctx(ctx, &channel_to_alice, &mut alice_ctx).await?; ctx.flow_controls() - .add_consumer("alice_ctx", channel_to_bob.flow_control_id()); + .add_consumer(&"alice_ctx".into(), channel_to_bob.flow_control_id()); message_should_pass_with_ctx(ctx, &channel_to_alice, &mut alice_ctx).await?; Ok(()) diff --git a/implementations/rust/ockam/ockam_identity/tests/update_route.rs b/implementations/rust/ockam/ockam_identity/tests/update_route.rs index d74aabbd36c..51569911dad 100644 --- a/implementations/rust/ockam/ockam_identity/tests/update_route.rs +++ b/implementations/rust/ockam/ockam_identity/tests/update_route.rs @@ -12,30 +12,31 @@ async fn test_update_decryptor_route(ctx: &mut Context) -> Result<()> { let alice = identities_creation.create_identity().await?; let bob = identities_creation.create_identity().await?; - let bob_listener = secure_channels - .create_secure_channel_listener(ctx, &bob, "bob", SecureChannelListenerOptions::new()) - .await?; + let bob_listener = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob", + SecureChannelListenerOptions::new(), + )?; let alice_channel = secure_channels .create_secure_channel(ctx, &alice, route!["bob"], SecureChannelOptions::new()) .await?; - let mut child_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "child", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut child_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "child", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; ctx.flow_controls() - .add_consumer("child", alice_channel.flow_control_id()); + .add_consumer(&"child".into(), alice_channel.flow_control_id()); ctx.flow_controls() - .add_consumer("child", bob_listener.flow_control_id()); + .add_consumer(&"child".into(), bob_listener.flow_control_id()); child_ctx .send( - route![alice_channel.clone(), child_ctx.address()], + route![alice_channel.clone(), child_ctx.primary_address().clone()], "Hello, Bob!".to_string(), ) .await?; @@ -54,7 +55,7 @@ async fn test_update_decryptor_route(ctx: &mut Context) -> Result<()> { child_ctx .send( - route![alice_channel.clone(), child_ctx.address()], + route![alice_channel.clone(), child_ctx.primary_address().clone()], "Hello, Bob!".to_string(), ) .await?; @@ -74,7 +75,7 @@ async fn test_update_decryptor_route(ctx: &mut Context) -> Result<()> { #[ockam_macros::test] async fn test_update_decryptor_route_tcp(ctx: &mut Context) -> Result<()> { - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let tcp_listener1 = tcp.listen("127.0.0.1:0", TcpListenerOptions::new()).await?; let tcp_listener2 = tcp.listen("127.0.0.1:0", TcpListenerOptions::new()).await?; @@ -92,16 +93,14 @@ async fn test_update_decryptor_route_tcp(ctx: &mut Context) -> Result<()> { let alice = identities_creation.create_identity().await?; let bob = identities_creation.create_identity().await?; - let bob_listener = secure_channels - .create_secure_channel_listener( - ctx, - &bob, - "bob", - SecureChannelListenerOptions::new() - .as_consumer(tcp_listener1.flow_control_id()) - .as_consumer(tcp_listener2.flow_control_id()), - ) - .await?; + let bob_listener = secure_channels.create_secure_channel_listener( + ctx, + &bob, + "bob", + SecureChannelListenerOptions::new() + .as_consumer(tcp_listener1.flow_control_id()) + .as_consumer(tcp_listener2.flow_control_id()), + )?; let alice_channel = secure_channels .create_secure_channel( @@ -112,22 +111,20 @@ async fn test_update_decryptor_route_tcp(ctx: &mut Context) -> Result<()> { ) .await?; - let mut child_ctx = ctx - .new_detached_with_mailboxes(Mailboxes::main( - "child", - Arc::new(AllowAll), - Arc::new(AllowAll), - )) - .await?; + let mut child_ctx = ctx.new_detached_with_mailboxes(Mailboxes::primary( + "child", + Arc::new(AllowAll), + Arc::new(AllowAll), + ))?; ctx.flow_controls() - .add_consumer("child", alice_channel.flow_control_id()); + .add_consumer(&"child".into(), alice_channel.flow_control_id()); ctx.flow_controls() - .add_consumer("child", bob_listener.flow_control_id()); + .add_consumer(&"child".into(), bob_listener.flow_control_id()); child_ctx .send( - route![alice_channel.clone(), child_ctx.address()], + route![alice_channel.clone(), child_ctx.primary_address().clone()], "Hello, Bob!".to_string(), ) .await?; @@ -142,13 +139,13 @@ async fn test_update_decryptor_route_tcp(ctx: &mut Context) -> Result<()> { assert_eq!("Hello, Alice!", msg.into_body()?); - tcp_connection1.stop(ctx).await?; + tcp_connection1.stop(ctx)?; alice_channel.update_remote_node_route(route![tcp_connection2])?; child_ctx .send( - route![alice_channel.clone(), child_ctx.address()], + route![alice_channel.clone(), child_ctx.primary_address().clone()], "Hello, Bob!".to_string(), ) .await?; diff --git a/implementations/rust/ockam/ockam_macros/README.md b/implementations/rust/ockam/ockam_macros/README.md index 457906ac66d..af99ce00867 100644 --- a/implementations/rust/ockam/ockam_macros/README.md +++ b/implementations/rust/ockam/ockam_macros/README.md @@ -10,7 +10,7 @@ and trustfully with cloud services and other devices. This crate provides shared macros to: - - clone structs asynchronously + - faillable clone structs - create an ockam node and access its `Context` - write some node-related tests diff --git a/implementations/rust/ockam/ockam_macros/src/internals/symbol.rs b/implementations/rust/ockam/ockam_macros/src/internals/symbol.rs index 574602253b6..f666af63b2e 100644 --- a/implementations/rust/ockam/ockam_macros/src/internals/symbol.rs +++ b/implementations/rust/ockam/ockam_macros/src/internals/symbol.rs @@ -12,7 +12,7 @@ pub(crate) const OCKAM_CRATE: Symbol = Symbol("crate"); pub(crate) const TIMEOUT_MS: Symbol = Symbol("timeout"); // Derive's helper attributes -pub(crate) const ASYNC_TRY_CLONE: Symbol = Symbol("async_try_clone"); +pub(crate) const TRY_CLONE: Symbol = Symbol("try_clone"); impl PartialEq for Ident { fn eq(&self, word: &Symbol) -> bool { diff --git a/implementations/rust/ockam/ockam_macros/src/lib.rs b/implementations/rust/ockam/ockam_macros/src/lib.rs index da52a366f3b..697cca8b4fd 100644 --- a/implementations/rust/ockam/ockam_macros/src/lib.rs +++ b/implementations/rust/ockam/ockam_macros/src/lib.rs @@ -1,6 +1,6 @@ //! This crate provides shared macros to: //! -//! - clone structs asynchronously +//! - faillable clone structs //! - create an ockam node and access its `Context` //! - write some node-related tests //! @@ -20,18 +20,18 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput, ItemFn}; -mod async_try_clone_derive; mod internals; mod message_derive; mod node_attribute; mod node_test_attribute; +mod try_clone_derive; mod vault_test_attribute; -/// Implements the [`AsyncTryClone`](https://docs.rs/ockam_core/latest/ockam_core/traits/trait.AsyncTryClone.html) trait for a type. +/// Implements the [`TryClone`](https://docs.rs/ockam_core/latest/ockam_core/traits/trait.TryClone.html) trait for a type. /// /// The macro supports the following attributes: /// -/// - `#[async_try_clone(crate = "...")]`: specify a path to the crate that +/// - `#[try_clone(crate = "...")]`: specify a path to the crate that /// will be used to import the items required by the macro. This can be /// helpful when using the macro from an internal `ockam` crate. Defaults /// to `ockam`. @@ -39,16 +39,16 @@ mod vault_test_attribute; /// Example of use: /// /// ```ignore -/// #[derive(ockam::AsyncTryClone)] -/// #[async_try_clone(crate = "ockam")] +/// #[derive(ockam::TryClone)] +/// #[try_clone(crate = "ockam")] /// pub struct MyStruct { /// a: u32, /// } /// ``` -#[proc_macro_derive(AsyncTryClone, attributes(async_try_clone))] -pub fn async_try_clone_derive(input: TokenStream) -> TokenStream { +#[proc_macro_derive(TryClone, attributes(try_clone))] +pub fn try_clone_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); - async_try_clone_derive::expand(input) + try_clone_derive::expand(input) .unwrap_or_else(to_compile_errors) .into() } @@ -92,7 +92,7 @@ pub fn message_derive(input: TokenStream) -> TokenStream { /// ```ignore /// #[ockam::node] /// async fn main(mut ctx: ockam::Context) -> ockam::Result<()> { -/// ctx.stop().await +/// ctx.shutdown_node().await /// } /// ``` #[proc_macro_attribute] @@ -126,7 +126,7 @@ pub fn node(args: TokenStream, item: TokenStream) -> TokenStream { /// ```ignore /// #[ockam::test] /// async fn main(ctx: &mut ockam::Context) -> ockam::Result<()> { -/// ctx.stop().await +/// ctx.shutdown_node().await /// } /// ``` #[proc_macro_attribute] diff --git a/implementations/rust/ockam/ockam_macros/src/node_test_attribute.rs b/implementations/rust/ockam/ockam_macros/src/node_test_attribute.rs index 84a90de99be..74a5a2450b6 100644 --- a/implementations/rust/ockam/ockam_macros/src/node_test_attribute.rs +++ b/implementations/rust/ockam/ockam_macros/src/node_test_attribute.rs @@ -14,14 +14,14 @@ use crate::internals::{ast, ast::FnVariable, check, ctx::Context, symbol::*}; /// ```ignore /// #[ockam::test] /// async fn my_test(ctx: &mut ockam::Context) -> ockam::Result<()> { -/// ctx.stop().await +/// ctx.shutdown_node().await /// } /// ``` /// /// Will be expanded to (ignoring part of the code generated by the compiler to run the test): /// ```ignore /// async fn _my_test(ctx: &mut ockam::Context) -> ockam::Result<()> { -/// ctx.stop().await +/// ctx.shutdown_node().await /// } /// /// fn expand() { @@ -43,14 +43,14 @@ use crate::internals::{ast, ast::FnVariable, check, ctx::Context, symbol::*}; /// { /// Ok(r) => { /// if r.is_err() { -/// let _ = AssertUnwindSafe(async { ctx.stop().await.unwrap(); }) +/// let _ = AssertUnwindSafe(async { ctx.shutdown_node().await.unwrap(); }) /// .catch_unwind() /// .await; /// } /// r /// } /// Err(_) => { -/// let _ = AssertUnwindSafe(async { ctx.stop().await.unwrap(); }) +/// let _ = AssertUnwindSafe(async { ctx.shutdown_node().await.unwrap(); }) /// .catch_unwind() /// .await; /// ::core::panicking::panic_fmt(::core::fmt::Arguments::new_v1( @@ -81,7 +81,7 @@ fn output(mut cont: Container) -> TokenStream { } }; let ctx_stop_stmt = quote! { - let _ = AssertUnwindSafe(async { let _ = #ctx_ident.stop().await; }) + let _ = AssertUnwindSafe(async { let _ = #ctx_ident.shutdown_node().await; }) .catch_unwind() .await; }; diff --git a/implementations/rust/ockam/ockam_macros/src/async_try_clone_derive.rs b/implementations/rust/ockam/ockam_macros/src/try_clone_derive.rs similarity index 85% rename from implementations/rust/ockam/ockam_macros/src/async_try_clone_derive.rs rename to implementations/rust/ockam/ockam_macros/src/try_clone_derive.rs index 37fec33f440..7a0fca17818 100644 --- a/implementations/rust/ockam/ockam_macros/src/async_try_clone_derive.rs +++ b/implementations/rust/ockam/ockam_macros/src/try_clone_derive.rs @@ -7,7 +7,7 @@ use syn::{ }; use crate::internals::ctx::Context; -use crate::internals::symbol::{ASYNC_TRY_CLONE, OCKAM_CRATE}; +use crate::internals::symbol::{OCKAM_CRATE, TRY_CLONE}; pub(crate) fn expand(input_derive: DeriveInput) -> Result> { let ctx = Context::new(); @@ -26,45 +26,25 @@ fn output(cont: Container) -> TokenStream { #field_name } }); - let fields_outer = fields.clone(); - let fields_async_impls = cont.data.struct_fields.iter().map(|f| { + let fields_impls = cont.data.struct_fields.iter().map(|f| { let field_name = &f.ident; quote! { - self.#field_name.async_try_clone() + let #field_name = self.#field_name.try_clone()?; } }); let trait_fn = quote! { - async fn async_try_clone(&self) -> #ockam_crate::Result{ - let results = #ockam_crate::compat::try_join!( - #(#fields_async_impls),* - ); - match results { - Ok((#(#fields_outer),* ,))=> { - Ok( - Self{ - #(#fields),* - } - ) - } - Err(e) => { - Err(e) + fn try_clone(&self) -> #ockam_crate::Result { + #(#fields_impls)* + + Ok( + Self{ + #(#fields),* } - } - } - }; - let async_trait: Attribute = match ockam_crate.to_string().as_str() { - "ockam" => parse_quote!(#[#ockam_crate::worker]), - "crate" | "ockam_core" => parse_quote!(#[#ockam_crate::async_trait]), - other => { - unreachable!( - "'crate' attribute is already checked in Attributes, got {}", - other ) } }; quote! { - #async_trait - impl #impl_generics #ockam_crate::AsyncTryClone for #struct_ident #ty_generics #where_clause { + impl #impl_generics #ockam_crate::TryClone for #struct_ident #ty_generics #where_clause { #trait_fn } } @@ -182,12 +162,12 @@ impl<'a> Data<'a> { t.bounds.push(parse_quote!(::core::marker::Send)); t.bounds.push(parse_quote!(::core::marker::Sync)); - // Generic simple type must also be AsyncTryClone + // Generic simple type must also be TryClone if simple_generic_fields .iter() .any(|s| s == &t.ident.to_string()) { - t.bounds.push(parse_quote!(#ockam_crate::AsyncTryClone)); + t.bounds.push(parse_quote!(#ockam_crate::TryClone)); } } } @@ -197,7 +177,7 @@ impl<'a> Data<'a> { for ty in complex_generic_fields { where_clause .predicates - .push(parse_quote!(#ty: #ockam_crate::AsyncTryClone)); + .push(parse_quote!(#ty: #ockam_crate::TryClone)); } generics @@ -270,7 +250,7 @@ impl Attributes { fn from_ast(ctx: &Context, attrs: &[Attribute]) -> Self { let mut ockam_crate = Attr::none(ctx, OCKAM_CRATE); for attr in attrs.iter() { - if attr.path().is_ident(&ASYNC_TRY_CLONE) { + if attr.path().is_ident(&TRY_CLONE) { attr.parse_nested_meta(|meta| { let value_expr: Expr = meta.value()?.parse()?; if let Ok(path) = parse_lit_into_path(ctx, OCKAM_CRATE, &value_expr) { diff --git a/implementations/rust/ockam/ockam_node/src/async_drop.rs b/implementations/rust/ockam/ockam_node/src/async_drop.rs deleted file mode 100644 index 4d90bd62de1..00000000000 --- a/implementations/rust/ockam/ockam_node/src/async_drop.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::router::Router; -use crate::tokio::sync::oneshot::{self, Receiver, Sender}; -use alloc::sync::Arc; -use ockam_core::Address; - -/// A helper to implement Drop mechanisms, but async -/// -/// This mechanism uses a Oneshot channel, which doesn't require an -/// async context to send into it (i.e. we can send a single message -/// from a `Drop` handler without needing to block on a future!) -/// -/// The receiver is then tasked to de-allocate the specified resource. -/// -/// This is not a very generic interface, i.e. it will only generate -/// stop_worker messages. If we want to reuse this mechanism, we may -/// also want to extend the API so that other resources can specify -/// additional metadata to generate messages. -pub struct AsyncDrop { - rx: Receiver
, - router: Arc, -} - -impl AsyncDrop { - /// Create a new AsyncDrop and AsyncDrop sender - /// - /// The `sender` parameter can simply be cloned from the parent - /// Context that creates this hook, while the `address` field must - /// refer to the address of the context that will be deallocated - /// this way. - pub fn new(router: Arc) -> (Self, Sender
) { - let (tx, rx) = oneshot::channel(); - (Self { rx, router }, tx) - } - - /// Wait for the cancellation of the channel and then send a - /// message to the router - /// - /// Because this code is run detached from its original context, - /// we can't handle any errors. - pub async fn run(self) { - if let Ok(addr) = self.rx.await { - debug!("Received AsyncDrop request for address: {}", addr); - if let Err(e) = self.router.stop_worker(&addr, true).await { - debug!("Failed sending AsyncDrop request to router: {}", e); - } - } - } -} diff --git a/implementations/rust/ockam/ockam_node/src/channel_types.rs b/implementations/rust/ockam/ockam_node/src/channel_types.rs index 2bf44354c42..ca299e6449b 100644 --- a/implementations/rust/ockam/ockam_node/src/channel_types.rs +++ b/implementations/rust/ockam/ockam_node/src/channel_types.rs @@ -14,28 +14,6 @@ pub fn message_channel() -> (MessageSender, MessageReceiver) { sync::mpsc::channel(8) } -/// Router sender -pub type RouterSender = sync::mpsc::Sender; -/// Router receiver -pub type RouterReceiver = sync::mpsc::Receiver; - -/// Create router channel -pub fn router_channel() -> (RouterSender, RouterReceiver) { - sync::mpsc::channel(64) -} - -// TODO: Consider replacing with oneshot - -/// Sender for small channels -pub type SmallSender = sync::mpsc::Sender; -/// Receiver for small channels -pub type SmallReceiver = sync::mpsc::Receiver; - -/// Create small channel (size 1) -pub fn small_channel() -> (SmallSender, SmallReceiver) { - sync::mpsc::channel(1) -} - /// Sender for oneshot channels pub type OneshotSender = sync::oneshot::Sender; /// Receiver for oneshot channels diff --git a/implementations/rust/ockam/ockam_node/src/context/context.rs b/implementations/rust/ockam/ockam_node/src/context/context.rs index da1dd88a74d..8c55d27eee9 100644 --- a/implementations/rust/ockam/ockam_node/src/context/context.rs +++ b/implementations/rust/ockam/ockam_node/src/context/context.rs @@ -1,39 +1,77 @@ -use crate::channel_types::SmallReceiver; +use crate::channel_types::MessageReceiver; use crate::tokio::runtime::Handle; -use crate::AsyncDropSender; use core::sync::atomic::AtomicUsize; use ockam_core::compat::collections::HashMap; use ockam_core::compat::sync::{Arc, RwLock}; use ockam_core::compat::time::Duration; -use ockam_core::compat::{string::String, vec::Vec}; +use ockam_core::compat::vec::Vec; use ockam_core::flow_control::FlowControls; #[cfg(feature = "std")] use ockam_core::OpenTelemetryContext; use ockam_core::{ - async_trait, Address, AddressAndMetadata, AddressMetadata, Error, Mailboxes, RelayMessage, - Result, TransportType, + async_trait, Address, AddressMetadata, Error, Mailboxes, RelayMessage, Result, TransportType, }; use crate::router::Router; #[cfg(feature = "std")] use core::fmt::{Debug, Formatter}; +use ockam_core::compat::sync::Weak; use ockam_core::errcode::{Kind, Origin}; use ockam_transport_core::Transport; /// A default timeout in seconds pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30); +/// Context mode depending on the fact if it's attached to a Worker or a Processor +#[derive(Clone, Copy, Debug)] +pub enum ContextMode { + /// Without a Worker or a Processor + Detached, + /// With a Worker or a Processor + Attached, +} + +/// Higher value means the worker is shutdown earlier +#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)] +pub enum WorkerShutdownPriority { + /// 1 + Priority1, + /// 2 + Priority2, + /// 3 + Priority3, + /// 4 + #[default] + Priority4, + /// 5 + Priority5, + /// 6 + Priority6, + /// 7 + Priority7, +} + +impl WorkerShutdownPriority { + /// All possible values in descending order + pub fn all_descending_order() -> [WorkerShutdownPriority; 7] { + use WorkerShutdownPriority::*; + [ + Priority7, Priority6, Priority5, Priority4, Priority3, Priority2, Priority1, + ] + } +} + /// Context contains Node state and references to the runtime. pub struct Context { pub(super) mailboxes: Mailboxes, - pub(super) router: Arc, - pub(super) rt: Handle, - pub(super) receiver: SmallReceiver, - pub(super) async_drop_sender: Option, + pub(super) router: Weak, + pub(super) runtime_handle: Handle, + pub(super) receiver: MessageReceiver, pub(super) mailbox_count: Arc, /// List of transports used to resolve external addresses to local workers in routes pub(super) transports: Arc>>>, pub(super) flow_controls: FlowControls, + pub(super) mode: ContextMode, #[cfg(feature = "std")] pub(super) tracing_context: OpenTelemetryContext, } @@ -50,7 +88,8 @@ impl Debug for Context { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.debug_struct("Context") .field("mailboxes", &self.mailboxes) - .field("runtime", &self.rt) + .field("runtime", &self.runtime_handle) + .field("mode", &self.mode) .finish() } } @@ -58,7 +97,7 @@ impl Debug for Context { impl Context { /// Return runtime clone pub fn runtime(&self) -> &Handle { - &self.rt + &self.runtime_handle } /// Return mailbox_count clone @@ -66,24 +105,26 @@ impl Context { self.mailbox_count.clone() } - /// Return a reference to sender - pub(crate) fn router(&self) -> Arc { - self.router.clone() + /// Reference to the Router + pub(crate) fn router(&self) -> Result> { + self.router + .upgrade() + .ok_or_else(|| Error::new(Origin::Node, Kind::Shutdown, "Failed to upgrade router")) } - /// Return the primary address of the current worker - pub fn address(&self) -> Address { - self.mailboxes.main_address() + /// Weak reference to the Router + pub(crate) fn router_weak(&self) -> Weak { + self.router.clone() } /// Return the primary address of the current worker - pub fn address_ref(&self) -> &Address { - self.mailboxes.main_address_ref() + pub fn primary_address(&self) -> &Address { + self.mailboxes.primary_address() } - /// Return all addresses of the current worker - pub fn addresses(&self) -> Vec
{ - self.mailboxes.addresses() + /// Return additional addresses of the current worker + pub fn additional_addresses(&self) -> impl Iterator { + self.mailboxes.additional_addresses() } /// Return a reference to the mailboxes of this context @@ -110,59 +151,26 @@ impl Context { } impl Context { - /// Assign the current worker to a cluster - /// - /// A cluster is a set of workers that should be stopped together - /// when the node is stopped or parts of the system are reloaded. - /// **This is not to be confused with supervisors!** - /// - /// By adding your worker to a cluster you signal to the runtime - /// that your worker may be depended on by other workers that - /// should be stopped first. - /// - /// **Your cluster name MUST NOT start with `_internals.` or - /// `ockam.`!** - /// - /// Clusters are de-allocated in reverse order of their - /// initialisation when the node is stopped. - pub async fn set_cluster>(&self, label: S) -> Result<()> { - self.router.set_cluster(self.address(), label.into()) - } - /// Return a list of all available worker addresses on a node - pub fn list_workers(&self) -> Vec
{ - self.router.list_workers() + pub fn list_workers(&self) -> Result> { + Ok(self.router()?.list_workers()) } /// Return true if a worker is already registered at this address - pub fn is_worker_registered_at(&self, address: &Address) -> bool { - self.router.is_worker_registered_at(address) - } - - /// Send a shutdown acknowledgement to the router - pub(crate) async fn stop_ack(&self) -> Result<()> { - self.router.stop_ack(self.address()).await + pub fn is_worker_registered_at(&self, address: &Address) -> Result { + Ok(self.router()?.is_worker_registered_at(address)) } /// Finds the terminal address of a route, if present - pub async fn find_terminal_address( + pub fn find_terminal_address<'a>( &self, - route: impl Into>, - ) -> Result> { - let addresses = route.into(); - if addresses.iter().any(|a| !a.transport_type().is_local()) { - return Err(Error::new( - Origin::Node, - Kind::Invalid, - "Only local addresses are allowed while looking for a terminal address", - )); - } - - Ok(self.router.find_terminal_address(addresses)) + addresses: impl Iterator, + ) -> Result> { + Ok(self.router()?.find_terminal_address(addresses)) } /// Read metadata for the provided address - pub fn get_metadata(&self, address: impl Into
) -> Option { - self.router.get_address_metadata(&address.into()) + pub fn get_metadata(&self, address: &Address) -> Result> { + Ok(self.router()?.get_address_metadata(address)) } } diff --git a/implementations/rust/ockam/ockam_node/src/context/context_lifecycle.rs b/implementations/rust/ockam/ockam_node/src/context/context_lifecycle.rs index ef694245ebd..266f3c4c294 100644 --- a/implementations/rust/ockam/ockam_node/src/context/context_lifecycle.rs +++ b/implementations/rust/ockam/ockam_node/src/context/context_lifecycle.rs @@ -1,55 +1,62 @@ -use core::time::Duration; - #[cfg(not(feature = "std"))] use crate::tokio; +use core::time::Duration; use ockam_core::compat::collections::HashMap; +use ockam_core::compat::sync::Weak; use ockam_core::compat::time::now; -use ockam_core::compat::{boxed::Box, sync::Arc, sync::RwLock}; +use ockam_core::compat::{sync::Arc, sync::RwLock}; use ockam_core::flow_control::FlowControls; #[cfg(feature = "std")] use ockam_core::OpenTelemetryContext; use ockam_core::{ - Address, AsyncTryClone, DenyAll, IncomingAccessControl, Mailboxes, OutgoingAccessControl, - Result, TransportType, + Address, AllowAll, DenyAll, IncomingAccessControl, Mailbox, Mailboxes, OutgoingAccessControl, + Result, TransportType, TryClone, }; use ockam_transport_core::Transport; -use tokio::runtime::Handle; - -use crate::async_drop::AsyncDrop; -use crate::channel_types::{message_channel, small_channel, SmallReceiver}; +use crate::channel_types::{message_channel, oneshot_channel, OneshotReceiver}; use crate::router::Router; -use crate::{debugger, Context}; +use crate::{debugger, Context, ContextMode}; use crate::{relay::CtrlSignal, router::SenderPair}; - -/// A special type of `Context` that has no worker relay and inherits -/// the parent `Context`'s access control -pub type DetachedContext = Context; - -/// A special sender type that connects a type to an AsyncDrop handler -pub type AsyncDropSender = tokio::sync::oneshot::Sender
; +use tokio::runtime::Handle; impl Drop for Context { fn drop(&mut self) { - if let Some(sender) = self.async_drop_sender.take() { - trace!("De-allocated detached context {}", self.address()); - if let Err(e) = sender.send(self.address()) { - warn!("Encountered error while dropping detached context: {}", e); + if let ContextMode::Detached = self.mode { + let router = match self.router() { + Ok(router) => router, + Err(_) => { + debug!( + "Can't upgrade router inside Context::drop: {}", + self.primary_address() + ); + return; + } + }; + + match router.stop_address(self.primary_address(), true) { + Ok(_) => {} + Err(e) => { + // That is OK during node stop + debug!( + "Encountered error while dropping detached context: {}. Err={}", + self.primary_address(), + e + ); + } } } } } -#[ockam_core::async_trait] -impl AsyncTryClone for Context { - async fn async_try_clone(&self) -> Result { +impl TryClone for Context { + fn try_clone(&self) -> Result { // TODO: @ac ignores parent Access Control. Should be documented somewhere self.new_detached( - Address::random_tagged("Context.async_try_clone.detached"), + Address::random_tagged("Context.try_clone.detached"), DenyAll, DenyAll, ) - .await } } @@ -62,24 +69,24 @@ impl Context { /// `async_drop_sender` must be provided when creating a detached /// Context type (i.e. not backed by a worker relay). #[allow(clippy::too_many_arguments)] - pub(crate) fn new( - rt: Handle, - router: Arc, + fn new( + runtime_handle: Handle, + router: Weak, mailboxes: Mailboxes, - async_drop_sender: Option, + mode: ContextMode, transports: Arc>>>, flow_controls: &FlowControls, #[cfg(feature = "std")] tracing_context: OpenTelemetryContext, - ) -> (Self, SenderPair, SmallReceiver) { + ) -> (Self, SenderPair, OneshotReceiver) { let (mailbox_tx, receiver) = message_channel(); - let (ctrl_tx, ctrl_rx) = small_channel(); + let (ctrl_tx, ctrl_rx) = oneshot_channel(); ( Self { - rt, + runtime_handle, router, mailboxes, + mode, receiver, - async_drop_sender, mailbox_count: Arc::new(0.into()), transports, flow_controls: flow_controls.clone(), @@ -94,32 +101,40 @@ impl Context { ) } - pub(crate) fn copy_with_mailboxes( - &self, - mailboxes: Mailboxes, - ) -> (Context, SenderPair, SmallReceiver) { - Context::new( - self.runtime().clone(), - self.router(), + pub(crate) fn create_app_context( + runtime_handle: Handle, + router: Weak, + flow_controls: &FlowControls, + #[cfg(feature = "std")] tracing_context: OpenTelemetryContext, + ) -> (Self, SenderPair, OneshotReceiver) { + let addr: Address = "app".into(); + let mailboxes = Mailboxes::new( + Mailbox::new(addr, None, Arc::new(AllowAll), Arc::new(AllowAll)), + vec![], + ); + + Self::new( + runtime_handle, + router, mailboxes, - None, - self.transports.clone(), - &self.flow_controls, + ContextMode::Detached, + Default::default(), + flow_controls, #[cfg(feature = "std")] - self.tracing_context(), + tracing_context, ) } - pub(crate) fn copy_with_mailboxes_detached( + pub(crate) fn new_with_mailboxes( &self, mailboxes: Mailboxes, - drop_sender: AsyncDropSender, - ) -> (Context, SenderPair, SmallReceiver) { - Context::new( + mode: ContextMode, + ) -> (Context, SenderPair, OneshotReceiver) { + Self::new( self.runtime().clone(), - self.router(), + self.router_weak(), mailboxes, - Some(drop_sender), + mode, self.transports.clone(), &self.flow_controls, #[cfg(feature = "std")] @@ -164,11 +179,8 @@ impl Context { } /// TODO basically we can just rename `Self::new_detached_impl()` - pub async fn new_detached_with_mailboxes( - &self, - mailboxes: Mailboxes, - ) -> Result { - let ctx = self.new_detached_impl(mailboxes).await?; + pub fn new_detached_with_mailboxes(&self, mailboxes: Mailboxes) -> Result { + let ctx = self.new_detached_impl(mailboxes)?; debugger::log_inherit_context("DETACHED_WITH_MB", self, &ctx); @@ -205,38 +217,31 @@ impl Context { /// Remove AddressRecord from router.map.address_records_map (return error if not found) /// Remove all alias in router.map.alias_map /// Remote all meta from router.map.address_metadata - pub async fn new_detached( + pub fn new_detached( &self, address: impl Into
, incoming: impl IncomingAccessControl, outgoing: impl OutgoingAccessControl, - ) -> Result { - let mailboxes = Mailboxes::main(address.into(), Arc::new(incoming), Arc::new(outgoing)); - let ctx = self.new_detached_impl(mailboxes).await?; + ) -> Result { + let mailboxes = Mailboxes::primary(address.into(), Arc::new(incoming), Arc::new(outgoing)); + let ctx = self.new_detached_impl(mailboxes)?; debugger::log_inherit_context("DETACHED", self, &ctx); Ok(ctx) } - async fn new_detached_impl(&self, mailboxes: Mailboxes) -> Result { - // A detached Context exists without a worker relay, which - // requires special shutdown handling. To allow the Drop - // handler to interact with the Node runtime, we use an - // AsyncDrop handler. - // - // This handler is spawned and listens for an event from the - // Drop handler, and then forwards a message to the Node - // router. - let (async_drop, drop_sender) = AsyncDrop::new(self.router.clone()); - self.rt.spawn(async_drop.run()); - + fn new_detached_impl(&self, mailboxes: Mailboxes) -> Result { // Create a new context and get access to the mailbox senders - let addresses = mailboxes.addresses(); - let (ctx, sender, _) = self.copy_with_mailboxes_detached(mailboxes, drop_sender); + let (ctx, sender, _) = self.new_with_mailboxes(mailboxes, ContextMode::Detached); - self.router - .start_worker(addresses, sender, true, vec![], self.mailbox_count.clone())?; + self.router()?.add_worker( + ctx.mailboxes(), + sender, + true, + Default::default(), + self.mailbox_count.clone(), + )?; Ok(ctx) } @@ -255,12 +260,11 @@ mod tests { // after a copy with new mailboxes the list of transports should be intact let mailboxes = Mailboxes::new(Mailbox::deny_all("address"), vec![]); - let (copy, _, _) = ctx.copy_with_mailboxes(mailboxes.clone()); + let (copy, _, _) = ctx.new_with_mailboxes(mailboxes.clone(), ContextMode::Attached); assert!(copy.is_transport_registered(transport.transport_type())); // after a detached copy with new mailboxes the list of transports should be intact - let (_, drop_sender) = AsyncDrop::new(ctx.router.clone()); - let (copy, _, _) = ctx.copy_with_mailboxes_detached(mailboxes, drop_sender); + let (copy, _, _) = ctx.new_with_mailboxes(mailboxes, ContextMode::Attached); assert!(copy.is_transport_registered(transport.transport_type())); Ok(()) } @@ -273,11 +277,11 @@ mod tests { TransportType::new(0) } - async fn resolve_address(&self, address: Address) -> Result
{ - Ok(address) + async fn resolve_address(&self, address: &Address) -> Result
{ + Ok(address.clone()) } - async fn disconnect(&self, _address: Address) -> Result<()> { + fn disconnect(&self, _address: &Address) -> Result<()> { Ok(()) } } diff --git a/implementations/rust/ockam/ockam_node/src/context/mod.rs b/implementations/rust/ockam/ockam_node/src/context/mod.rs index d37581d40d3..83923a1b93f 100644 --- a/implementations/rust/ockam/ockam_node/src/context/mod.rs +++ b/implementations/rust/ockam/ockam_node/src/context/mod.rs @@ -4,11 +4,10 @@ mod context_lifecycle; mod receive_message; mod register_router; mod send_message; -mod stop_env; +mod shutdown; mod transports; mod worker_lifecycle; pub use context::*; -pub use context_lifecycle::*; pub use receive_message::*; pub use send_message::*; diff --git a/implementations/rust/ockam/ockam_node/src/context/receive_message.rs b/implementations/rust/ockam/ockam_node/src/context/receive_message.rs index 8334d0b32c9..95c7c05dac5 100644 --- a/implementations/rust/ockam/ockam_node/src/context/receive_message.rs +++ b/implementations/rust/ockam/ockam_node/src/context/receive_message.rs @@ -61,7 +61,7 @@ impl Context { pub(crate) async fn receiver_next(&mut self) -> Result> { loop { let relay_msg = if let Some(msg) = self.receiver.recv().await.map(|msg| { - trace!("{}: received new message!", self.address()); + trace!("{}: received new message!", self.primary_address()); // First we update the mailbox fill metrics self.mailbox_count.fetch_sub(1, Ordering::Acquire); diff --git a/implementations/rust/ockam/ockam_node/src/context/register_router.rs b/implementations/rust/ockam/ockam_node/src/context/register_router.rs index 65e16c61999..0d9e8c3e09d 100644 --- a/implementations/rust/ockam/ockam_node/src/context/register_router.rs +++ b/implementations/rust/ockam/ockam_node/src/context/register_router.rs @@ -5,6 +5,6 @@ impl Context { // TODO: This method should be deprecated /// Register a router for a specific address type pub fn register>(&self, type_: TransportType, addr: A) -> Result<()> { - self.router.register_router(type_, addr.into()) + self.router()?.register_router(type_, addr.into()) } } diff --git a/implementations/rust/ockam/ockam_node/src/context/send_message.rs b/implementations/rust/ockam/ockam_node/src/context/send_message.rs index 91dd00ce763..11ac6398407 100644 --- a/implementations/rust/ockam/ockam_node/src/context/send_message.rs +++ b/implementations/rust/ockam/ockam_node/src/context/send_message.rs @@ -88,6 +88,7 @@ impl Context { let mailboxes = Mailboxes::new( Mailbox::new( address.clone(), + None, Arc::new(AllowAll), Arc::new(AllowOnwardAddress(next.clone())), ), @@ -100,10 +101,10 @@ impl Context { .map(|x| x.flow_control_id().clone()) { // To be able to receive the response - self.flow_controls.add_consumer(address, &flow_control_id); + self.flow_controls.add_consumer(&address, &flow_control_id); } - let mut child_ctx = self.new_detached_with_mailboxes(mailboxes).await?; + let mut child_ctx = self.new_detached_with_mailboxes(mailboxes)?; #[cfg(feature = "std")] child_ctx.set_tracing_context(self.tracing_context()); @@ -168,7 +169,7 @@ impl Context { R: Into, M: Message + Send + 'static, { - self.send_from_address(route.into(), msg, self.address()) + self.send_from_address(route.into(), msg, self.primary_address().clone()) .await } @@ -184,8 +185,13 @@ impl Context { R: Into, M: Message + Send + 'static, { - self.send_from_address_impl(route.into(), msg, self.address(), local_info) - .await + self.send_from_address_impl( + route.into(), + msg, + self.primary_address().clone(), + local_info, + ) + .await } /// Send a message to an address or via a fully-qualified route @@ -240,7 +246,7 @@ impl Context { } }; - let sender = self.router.resolve(&addr)?; + let sender = self.router()?.resolve(&addr)?; // Pack the payload into a TransportMessage let payload = msg.encode().map_err(|_| NodeError::Data.internal())?; @@ -265,7 +271,7 @@ impl Context { } // Pack local message into a RelayMessage wrapper - let relay_msg = RelayMessage::new(sending_address.clone(), addr, local_msg); + let relay_msg = RelayMessage::new(sending_address, addr, local_msg); debugger::log_outgoing_message(self, &relay_msg); @@ -300,7 +306,8 @@ impl Context { /// [`Context::send`]: crate::Context::send /// [`LocalMessage`]: ockam_core::LocalMessage pub async fn forward(&self, local_msg: LocalMessage) -> Result<()> { - self.forward_from_address(local_msg, self.address()).await + self.forward_from_address(local_msg, self.primary_address().clone()) + .await } /// Forward a transport message to its next routing destination @@ -337,7 +344,7 @@ impl Context { return Err(err); } }; - let sender = self.router.resolve(&addr)?; + let sender = self.router()?.resolve(&addr)?; // Pack the transport message into a RelayMessage wrapper let relay_msg = RelayMessage::new(sending_address, addr, local_msg); diff --git a/implementations/rust/ockam/ockam_node/src/context/shutdown.rs b/implementations/rust/ockam/ockam_node/src/context/shutdown.rs new file mode 100644 index 00000000000..7662a6987cc --- /dev/null +++ b/implementations/rust/ockam/ockam_node/src/context/shutdown.rs @@ -0,0 +1,35 @@ +use crate::Context; +use ockam_core::Result; + +impl Context { + /// Signal to the local runtime to shut down + /// + /// This call will hang until a safe shutdown has been completed. + /// The default timeout for a safe shutdown is 1 second. You can + /// change this behaviour by calling + /// [`Context::shutdown_node_with_timeout`](Context::shutdown_node_with_timeout) directly. + pub async fn shutdown_node(&self) -> Result<()> { + self.shutdown_node_with_timeout(1).await + } + + /// Signal to the local runtime to shut down + /// + /// This call will hang until a safe shutdown has been completed + /// or the desired timeout has been reached. + pub async fn shutdown_node_with_timeout(&self, seconds: u8) -> Result<()> { + let router = self.router()?; + + // Spawn a separate task, otherwise if this function is called from a worker, in can be + // cancelled, as worker run loop itself is stopped as a result of this call + let _handle = crate::spawn(async move { router.shutdown_graceful(seconds).await }); + + #[cfg(feature = "std")] + _handle.await.unwrap()?; + + // TODO: Would be cool to shutdown the Runtime here with a timeout in case router timed out, + // that would require more transparent ownership over the Runtime, since shutdown is + // consuming the value. + + Ok(()) + } +} diff --git a/implementations/rust/ockam/ockam_node/src/context/stop_env.rs b/implementations/rust/ockam/ockam_node/src/context/stop_env.rs deleted file mode 100644 index e6ce046b5ba..00000000000 --- a/implementations/rust/ockam/ockam_node/src/context/stop_env.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::Context; -use ockam_core::Result; - -impl Context { - /// Signal to the local runtime to shut down - /// - /// This call will hang until a safe shutdown has been completed. - /// The default timeout for a safe shutdown is 1 second. You can - /// change this behaviour by calling - /// [`Context::stop_timeout`](Context::stop_timeout) directly. - pub async fn stop(&self) -> Result<()> { - self.stop_timeout(1).await - } - - /// Signal to the local runtime to shut down - /// - /// This call will hang until a safe shutdown has been completed - /// or the desired timeout has been reached. - pub async fn stop_timeout(&self, seconds: u8) -> Result<()> { - self.router.clone().stop_graceful(seconds).await - } -} diff --git a/implementations/rust/ockam/ockam_node/src/context/transports.rs b/implementations/rust/ockam/ockam_node/src/context/transports.rs index 607490c9a2b..64ae40551d5 100644 --- a/implementations/rust/ockam/ockam_node/src/context/transports.rs +++ b/implementations/rust/ockam/ockam_node/src/context/transports.rs @@ -61,7 +61,7 @@ impl Context { for address in route.iter() { if !address.is_local() { if let Some(transport) = transports.get(&address.transport_type()) { - let transport_address = transport.resolve_address(address.clone()).await?; + let transport_address = transport.resolve_address(address).await?; resolved_address = Some(transport_address.clone()); resolved_route = resolved_route.append(transport_address); } else { @@ -141,11 +141,11 @@ mod tests { } /// This implementation simply marks each address as a local address - async fn resolve_address(&self, address: Address) -> Result
{ - Ok(Address::new(LOCAL, address.inner())) + async fn resolve_address(&self, address: &Address) -> Result
{ + Ok(Address::new(LOCAL, address.clone().inner())) } - async fn disconnect(&self, _address: Address) -> Result<()> { + fn disconnect(&self, _address: &Address) -> Result<()> { Ok(()) } } diff --git a/implementations/rust/ockam/ockam_node/src/context/worker_lifecycle.rs b/implementations/rust/ockam/ockam_node/src/context/worker_lifecycle.rs index c8cae5aa7da..3c04d117ea0 100644 --- a/implementations/rust/ockam/ockam_node/src/context/worker_lifecycle.rs +++ b/implementations/rust/ockam/ockam_node/src/context/worker_lifecycle.rs @@ -4,20 +4,6 @@ use ockam_core::{ Address, IncomingAccessControl, OutgoingAccessControl, Processor, Result, Worker, }; -enum AddressType { - Worker, - Processor, -} - -impl AddressType { - fn str(&self) -> &'static str { - match self { - AddressType::Worker => "worker", - AddressType::Processor => "processor", - } - } -} - impl Context { /// Start a new worker instance at the given address. Default AccessControl is AllowAll /// @@ -46,8 +32,8 @@ impl Context { /// type Message = String; /// } /// - /// async fn start_my_worker(ctx: &mut Context) -> Result<()> { - /// ctx.start_worker("my-worker-address", MyWorker).await + /// fn start_my_worker(ctx: &mut Context) -> Result<()> { + /// ctx.start_worker("my-worker-address", MyWorker) /// } /// ``` /// @@ -67,14 +53,13 @@ impl Context { /// WorkerRelay calls Worker::handle_message for each message until either /// stop signal is received (CtrlSignal::InterruptStop to AddressRecord::ctrl_tx) /// there are no messages coming to that receiver (the sender side is dropped) - pub async fn start_worker(&self, address: impl Into
, worker: W) -> Result<()> + pub fn start_worker(&self, address: impl Into
, worker: W) -> Result<()> where W: Worker, { WorkerBuilder::new(worker) .with_address(address) - .start(self) - .await?; + .start(self)?; Ok(()) } @@ -104,11 +89,11 @@ impl Context { /// type Message = String; /// } /// - /// async fn start_my_worker(ctx: &mut Context) -> Result<()> { - /// ctx.start_worker_with_access_control("my-worker-address", MyWorker, AllowAll, AllowAll).await + /// fn start_my_worker(ctx: &mut Context) -> Result<()> { + /// ctx.start_worker_with_access_control("my-worker-address", MyWorker, AllowAll, AllowAll) /// } /// ``` - pub async fn start_worker_with_access_control( + pub fn start_worker_with_access_control( &self, address: impl Into
, worker: W, @@ -122,8 +107,7 @@ impl Context { .with_address(address) .with_incoming_access_control(incoming) .with_outgoing_access_control(outgoing) - .start(self) - .await?; + .start(self)?; Ok(()) } @@ -150,14 +134,13 @@ impl Context { /// 7. ProcessorRelay is spawned as a tokio task: /// ProcessorRelay calls Processor::initialize /// ProcessorRelay calls Processor::process until either false is returned or stop signal is received (CtrlSignal::InterruptStop to AddressRecord::ctrl_tx) - pub async fn start_processor

(&self, address: impl Into

, processor: P) -> Result<()> + pub fn start_processor

(&self, address: impl Into

, processor: P) -> Result<()> where P: Processor, { ProcessorBuilder::new(processor) .with_address(address.into()) - .start(self) - .await?; + .start(self)?; Ok(()) } @@ -170,7 +153,7 @@ impl Context { /// message events, consider using /// [`start_worker()`](Self::start_worker) instead! /// - pub async fn start_processor_with_access_control

( + pub fn start_processor_with_access_control

( &self, address: impl Into

, processor: P, @@ -184,57 +167,13 @@ impl Context { .with_address(address) .with_incoming_access_control(incoming) .with_outgoing_access_control(outgoing) - .start(self) - .await?; + .start(self)?; Ok(()) } - /// Shut down a local worker by its primary address - /// - /// Approximate flow of stopping a worker: - /// - /// 1. StopWorker message -> Router - /// 2. Get AddressRecord - /// 3. Drop sender - /// 4. WorkerRelay calls Worker::shutdown - /// 5. StopAck message -> Router (from main_address) - /// 6. router.map.free_address(main_address) is called (given Router state is running): - /// remote main_address from router.map.stopping (it's not their anyway, unless in was a cluster and node was shutting down) - /// Remove AddressRecord from router.map.address_records_map (return error if not found) - /// Remove all alias in router.map.alias_map - /// Remote all meta from router.map.address_metadata - pub async fn stop_worker>(&self, addr: A) -> Result<()> { - self.stop_address(addr.into(), AddressType::Worker).await - } - - /// Shut down a local processor by its address - /// - /// Approximate flow of stopping a processor: - /// - /// 1. StopProcessor message -> Router - /// 2. Get AddressRecord - /// 3. Call AddressRecord::stop: - /// Send CtrlSignal::InterruptStop to AddressRecord::ctrl_tx - /// Set AddressRecord::state = AddressState::Stopping - /// 4. ProcessorRelay calls Processor::shutdown - /// 5. StopAck message -> Router (from main_address) - /// 6. router.map.free_address(main_address) is called (given Router state is running): - /// remote main_address from router.map.stopping (it's not their anyways unless in was a cluster and node was shutting down) - /// Remove AddressRecord from router.map.address_records_map (return error if not found) - /// Remove all alias in router.map.alias_map - /// Remote all meta from router.map.address_metadata - pub async fn stop_processor>(&self, addr: A) -> Result<()> { - self.stop_address(addr.into(), AddressType::Processor).await - } - - async fn stop_address(&self, addr: Address, t: AddressType) -> Result<()> { - debug!("Shutting down {} {}", t.str(), addr); - - // Send the stop request - match t { - AddressType::Worker => self.router.stop_worker(&addr, false).await, - AddressType::Processor => self.router.stop_processor(&addr).await, - } + /// Stop a Worker or a Processor running on given Address + pub fn stop_address(&self, address: &Address) -> Result<()> { + self.router()?.stop_address(address, false) } } diff --git a/implementations/rust/ockam/ockam_node/src/debugger.rs b/implementations/rust/ockam/ockam_node/src/debugger.rs index 65315fde17f..21936be9d41 100644 --- a/implementations/rust/ockam/ockam_node/src/debugger.rs +++ b/implementations/rust/ockam/ockam_node/src/debugger.rs @@ -8,7 +8,6 @@ use ockam_core::{Address, Mailbox, Mailboxes}; #[cfg(feature = "debugger")] use ockam_core::compat::{ - collections::BTreeMap, sync::{Arc, RwLock}, vec::Vec, }; @@ -23,13 +22,13 @@ use core::{ #[derive(Default)] struct Debugger { /// Map context inheritance from parent main `Mailbox` to child [`Mailboxes`] - inherited_mb: Arc>>>, + inherited_mb: Arc>>>, /// Map message destination to source - incoming: Arc>>>, + incoming: Arc>>>, /// Map message destination `Mailbox` to source [`Mailbox`] - incoming_mb: Arc>>>, + incoming_mb: Arc>>>, /// Map message source to destinations - outgoing: Arc>>>, + outgoing: Arc>>>, } /// Return a mutable reference to the global debugger instance @@ -88,9 +87,9 @@ pub fn log_incoming_message(_receiving_ctx: &Context, _relay_msg: &RelayMessage) tracing::trace!( "log_incoming_message #{:03}: {} -> {} ({})", COUNTER.fetch_add(1, Ordering::Relaxed), - _relay_msg.source(), // sending address - _relay_msg.destination(), // receiving address - _receiving_ctx.address(), // actual receiving context address + _relay_msg.source(), // sending address + _relay_msg.destination(), // receiving address + _receiving_ctx.primary_address(), // actual receiving context address ); match instance().incoming.write() { @@ -137,9 +136,9 @@ pub fn log_outgoing_message(_sending_ctx: &Context, _relay_msg: &RelayMessage) { tracing::trace!( "log_outgoing_message #{:03}: {} ({}) -> {}", COUNTER.fetch_add(1, Ordering::Relaxed), - _relay_msg.source(), // sending address - _sending_ctx.address(), // actual sending context address - _relay_msg.destination(), // receiving address + _relay_msg.source(), // sending address + _sending_ctx.primary_address(), // actual sending context address + _relay_msg.destination(), // receiving address ); match instance().outgoing.write() { @@ -187,7 +186,7 @@ pub fn log_inherit_context(_tag: &str, _parent: &Context, _child: &Context) { match instance().inherited_mb.write() { Ok(mut inherited_mb) => { - let parent = _parent.mailboxes().main_mailbox().clone(); + let parent = _parent.mailboxes().primary_mailbox().clone(); let children = _child.mailboxes().clone(); inherited_mb .entry(parent) @@ -250,8 +249,8 @@ pub fn generate_graphs(w: &mut BufWriter) -> io::Result<()> { } // generate mailboxes set - use ockam_core::compat::collections::BTreeSet; - let mut mailboxes = BTreeSet::new(); + use ockam_core::compat::collections::HashSet; + let mut mailboxes = HashSet::new(); if let Ok(inherited_mb) = instance().inherited_mb.read() { for (parent, children) in inherited_mb.iter() { for child in children.iter() { diff --git a/implementations/rust/ockam/ockam_node/src/delayed.rs b/implementations/rust/ockam/ockam_node/src/delayed.rs index 9899d9024a8..3dbc3435128 100644 --- a/implementations/rust/ockam/ockam_node/src/delayed.rs +++ b/implementations/rust/ockam/ockam_node/src/delayed.rs @@ -22,18 +22,14 @@ impl Drop for DelayedEvent { impl DelayedEvent { /// Create a heartbeat - pub async fn create( - ctx: &Context, - destination_addr: impl Into
, - msg: M, - ) -> Result { + pub fn create(ctx: &Context, destination_addr: impl Into
, msg: M) -> Result { let destination_addr = destination_addr.into(); - let mailboxes = Mailboxes::main( + let mailboxes = Mailboxes::primary( Address::random_tagged("DelayedEvent.create"), Arc::new(DenyAll), Arc::new(AllowOnwardAddress(destination_addr.clone())), ); - let child_ctx = ctx.new_detached_with_mailboxes(mailboxes).await?; + let child_ctx = ctx.new_detached_with_mailboxes(mailboxes)?; let heartbeat = Self { ctx: Arc::new(child_ctx), @@ -46,8 +42,8 @@ impl DelayedEvent { } /// Address used to send messages to destination address - pub fn address(&self) -> Address { - self.ctx.address() + pub fn address(&self) -> &Address { + self.ctx.primary_address() } } @@ -60,7 +56,7 @@ impl DelayedEvent { } /// Schedule heartbeat. Cancels already scheduled heartbeat if there is such heartbeat - pub async fn schedule(&mut self, duration: Duration) -> Result<()> { + pub fn schedule(&mut self, duration: Duration) -> Result<()> { self.cancel(); let destination_addr = self.destination_addr.clone(); @@ -127,20 +123,19 @@ mod tests { ctx: &mut Context, ) -> Result<()> { let msgs_count = Arc::new(AtomicI8::new(0)); - let mut heartbeat = - DelayedEvent::create(ctx, "counting_worker", "Hello".to_string()).await?; + let mut heartbeat = DelayedEvent::create(ctx, "counting_worker", "Hello".to_string())?; let worker = CountingWorker { msgs_count: msgs_count.clone(), }; - ctx.start_worker("counting_worker", worker).await?; + ctx.start_worker("counting_worker", worker)?; - heartbeat.schedule(Duration::from_millis(100)).await?; + heartbeat.schedule(Duration::from_millis(100))?; sleep(Duration::from_millis(150)).await; - heartbeat.schedule(Duration::from_millis(100)).await?; + heartbeat.schedule(Duration::from_millis(100))?; sleep(Duration::from_millis(150)).await; - heartbeat.schedule(Duration::from_millis(100)).await?; + heartbeat.schedule(Duration::from_millis(100))?; sleep(Duration::from_millis(150)).await; assert_eq!(3, msgs_count.load(Ordering::Relaxed)); @@ -151,18 +146,17 @@ mod tests { #[ockam_macros::test(crate = "crate")] async fn rescheduling__counting_worker__aborts_existing(ctx: &mut Context) -> Result<()> { let msgs_count = Arc::new(AtomicI8::new(0)); - let mut heartbeat = - DelayedEvent::create(ctx, "counting_worker", "Hello".to_string()).await?; + let mut heartbeat = DelayedEvent::create(ctx, "counting_worker", "Hello".to_string())?; let worker = CountingWorker { msgs_count: msgs_count.clone(), }; - ctx.start_worker("counting_worker", worker).await?; + ctx.start_worker("counting_worker", worker)?; - heartbeat.schedule(Duration::from_millis(100)).await?; - heartbeat.schedule(Duration::from_millis(100)).await?; - heartbeat.schedule(Duration::from_millis(100)).await?; + heartbeat.schedule(Duration::from_millis(100))?; + heartbeat.schedule(Duration::from_millis(100))?; + heartbeat.schedule(Duration::from_millis(100))?; sleep(Duration::from_millis(150)).await; assert_eq!(1, msgs_count.load(Ordering::Relaxed)); @@ -173,18 +167,17 @@ mod tests { #[ockam_macros::test(crate = "crate")] async fn cancel__counting_worker__aborts_existing(ctx: &mut Context) -> Result<()> { let msgs_count = Arc::new(AtomicI8::new(0)); - let mut heartbeat = - DelayedEvent::create(ctx, "counting_worker", "Hello".to_string()).await?; + let mut heartbeat = DelayedEvent::create(ctx, "counting_worker", "Hello".to_string())?; let worker = CountingWorker { msgs_count: msgs_count.clone(), }; - ctx.start_worker("counting_worker", worker).await?; + ctx.start_worker("counting_worker", worker)?; - heartbeat.schedule(Duration::from_millis(100)).await?; + heartbeat.schedule(Duration::from_millis(100))?; sleep(Duration::from_millis(150)).await; - heartbeat.schedule(Duration::from_millis(200)).await?; + heartbeat.schedule(Duration::from_millis(200))?; sleep(Duration::from_millis(100)).await; heartbeat.cancel(); sleep(Duration::from_millis(300)).await; @@ -197,18 +190,17 @@ mod tests { #[ockam_macros::test(crate = "crate")] async fn drop__counting_worker__aborts_existing(ctx: &mut Context) -> Result<()> { let msgs_count = Arc::new(AtomicI8::new(0)); - let mut heartbeat = - DelayedEvent::create(ctx, "counting_worker", "Hello".to_string()).await?; + let mut heartbeat = DelayedEvent::create(ctx, "counting_worker", "Hello".to_string())?; let worker = CountingWorker { msgs_count: msgs_count.clone(), }; - ctx.start_worker("counting_worker", worker).await?; + ctx.start_worker("counting_worker", worker)?; - heartbeat.schedule(Duration::from_millis(100)).await?; + heartbeat.schedule(Duration::from_millis(100))?; sleep(Duration::from_millis(150)).await; - heartbeat.schedule(Duration::from_millis(200)).await?; + heartbeat.schedule(Duration::from_millis(200))?; sleep(Duration::from_millis(100)).await; drop(heartbeat); sleep(Duration::from_millis(300)).await; diff --git a/implementations/rust/ockam/ockam_node/src/executor.rs b/implementations/rust/ockam/ockam_node/src/executor.rs index 510a1221cc9..ad26a3238ab 100644 --- a/implementations/rust/ockam/ockam_node/src/executor.rs +++ b/implementations/rust/ockam/ockam_node/src/executor.rs @@ -1,11 +1,9 @@ -#[cfg(feature = "std")] -use crate::runtime; -use crate::{ - router::{Router, SenderPair}, - tokio::runtime::Runtime, -}; +use crate::{router::Router, tokio::runtime::Runtime}; use core::future::Future; -use ockam_core::{compat::sync::Arc, Address, Result}; +use ockam_core::{ + compat::sync::{Arc, Weak}, + Result, +}; #[cfg(feature = "metrics")] use crate::metrics::Metrics; @@ -25,6 +23,13 @@ use ockam_core::{ Error, }; +// TODO: Either make this the only one place we create runtime, or vice verse: remove it from here +#[cfg(feature = "std")] +pub(crate) static RUNTIME: once_cell::sync::Lazy>> = + once_cell::sync::Lazy::new(|| { + ockam_core::compat::sync::Mutex::new(Some(Runtime::new().unwrap())) + }); + /// Underlying Ockam node executor /// /// This type is a small wrapper around an inner async runtime (`tokio` by @@ -32,7 +37,7 @@ use ockam_core::{ /// `ockam::node` function annotation instead! pub struct Executor { /// Reference to the runtime needed to spawn tasks - rt: Arc, + runtime: Arc, /// Application router router: Arc, /// Metrics collection endpoint @@ -42,38 +47,25 @@ pub struct Executor { impl Executor { /// Create a new Ockam node [`Executor`] instance - pub fn new(rt: Arc, flow_controls: &FlowControls) -> Self { + pub fn new(runtime: Arc, flow_controls: &FlowControls) -> Self { let router = Arc::new(Router::new(flow_controls)); #[cfg(feature = "metrics")] - let metrics = Metrics::new(&rt, router.get_metrics_readout()); + let metrics = Metrics::new(runtime.handle().clone(), router.get_metrics_readout()); Self { - rt, + runtime, router, #[cfg(feature = "metrics")] metrics, } } - /// Get access to the internal message sender - pub(crate) fn router(&self) -> Arc { - self.router.clone() - } - - /// Initialize the root application worker - pub(crate) fn initialize_system>( - &self, - address: S, - senders: SenderPair, - ) -> Result<()> { - trace!("Initializing node executor"); - self.router.init(address.into(), senders) + /// Get access to the Router + pub(crate) fn router(&self) -> Weak { + Arc::downgrade(&self.router) } /// Initialise and run the Ockam node executor context /// - /// In this background this launches async execution of the Ockam - /// router, while blocking execution on the provided future. - /// /// Any errors encountered by the router or provided application /// code will be returned from this function. #[cfg(feature = "std")] @@ -87,16 +79,11 @@ impl Executor { #[cfg(feature = "metrics")] let alive = Arc::new(AtomicBool::from(true)); #[cfg(feature = "metrics")] - self.rt.spawn( - self.metrics - .clone() - .run(alive.clone()) - .with_current_context(), - ); + self.metrics.clone().spawn(alive.clone()); // Spawn user code second let future = Executor::wrapper(self.router.clone(), future); - let join_body = self.rt.spawn(future.with_current_context()); + let join_body = self.runtime.spawn(future.with_current_context()); // Shut down metrics collector #[cfg(feature = "metrics")] @@ -104,51 +91,12 @@ impl Executor { // Last join user code let res = self - .rt + .runtime .block_on(join_body) .map_err(|e| Error::new(Origin::Executor, Kind::Unknown, e))?; - Ok(res) - } - - /// Initialise and run the Ockam node executor context - /// - /// In this background this launches async execution of the Ockam - /// router, while blocking execution on the provided future. - /// - /// Any errors encountered by the router or provided application - /// code will be returned from this function. - /// - /// Don't abort the router in case of a failure - #[cfg(feature = "std")] - pub fn execute_no_abort(&mut self, future: F) -> Result - where - F: Future + Send + 'static, - T: Send + 'static, - { - // Spawn the metrics collector first - #[cfg(feature = "metrics")] - let alive = Arc::new(AtomicBool::from(true)); - #[cfg(feature = "metrics")] - self.rt.spawn( - self.metrics - .clone() - .run(alive.clone()) - .with_current_context(), - ); - - // Spawn user code second - let join_body = self.rt.spawn(future.with_current_context()); - - // Shut down metrics collector - #[cfg(feature = "metrics")] - alive.fetch_or(true, Ordering::Acquire); - - // Last join user code - let res = self - .rt - .block_on(join_body) - .map_err(|e| Error::new(Origin::Executor, Kind::Unknown, e))?; + // TODO: Shutdown Runtime if we exclusively own it. Which should be always except when we + // run multiple nodes inside the same process Ok(res) } @@ -161,18 +109,13 @@ impl Executor { { match future.await { Ok(val) => { + debug!("Wait for router termination..."); router.wait_termination().await; + debug!("Router terminated successfully!..."); Ok(val) } Err(e) => { - // We earlier sent the AbortNode message to the router here. - // It failed because the router state was not set to `Stopping` - // But sending Graceful shutdown message works because, it internally does that. - // - // I think way AbortNode is implemented right now, it is more of an - // internal/private message not meant to be directly used, without changing the - // router state. - if let Err(error) = router.stop_graceful(1).await { + if let Err(error) = router.shutdown_graceful(1).await { error!("Failed to stop gracefully: {}", error); } Err(e) @@ -189,7 +132,7 @@ impl Executor { F: Future + Send + 'static, F::Output: Send + 'static, { - let lock = runtime::RUNTIME.lock().unwrap(); + let lock = RUNTIME.lock().unwrap(); let rt = lock.as_ref().expect("Runtime was consumed"); let join_body = rt.spawn(future.with_current_context()); rt.block_on(join_body.with_current_context()) @@ -210,12 +153,12 @@ impl Executor { F: Future + Send + 'static, F::Output: Send + 'static, { - let _join = self.rt.spawn(future); + let _join = self.runtime.spawn(future); let router = self.router.clone(); // Block this task executing the primary message router, // returning any critical failures that it encounters. - crate::tokio::runtime::execute(&self.rt, async move { + crate::tokio::runtime::execute(&self.runtime, async move { router.wait_termination().await; }); Ok(()) diff --git a/implementations/rust/ockam/ockam_node/src/lib.rs b/implementations/rust/ockam/ockam_node/src/lib.rs index 06dcfe71497..41c7d75ee23 100644 --- a/implementations/rust/ockam/ockam_node/src/lib.rs +++ b/implementations/rust/ockam/ockam_node/src/lib.rs @@ -52,7 +52,6 @@ pub mod callback; /// Helper workers pub mod workers; -mod async_drop; mod context; mod delayed; mod error; @@ -61,17 +60,12 @@ mod node; mod processor_builder; mod relay; mod router; -mod shutdown; /// Support for storing persistent values pub mod storage; mod worker_builder; -/// Singleton for the runtime executor -#[cfg(feature = "std")] -pub mod runtime; - #[cfg(feature = "watchdog")] mod watchdog; @@ -80,7 +74,6 @@ pub use delayed::*; pub use error::*; pub use executor::*; pub use processor_builder::ProcessorBuilder; -pub use shutdown::*; #[cfg(feature = "std")] pub use storage::database; pub use worker_builder::WorkerBuilder; @@ -94,11 +87,11 @@ use tokio::task; #[doc(hidden)] #[cfg(feature = "std")] -pub fn spawn(f: F) +pub fn spawn(f: F) -> task::JoinHandle where F::Output: Send, { - task::spawn(f); + task::spawn(f) } #[cfg(not(feature = "std"))] diff --git a/implementations/rust/ockam/ockam_node/src/metrics.rs b/implementations/rust/ockam/ockam_node/src/metrics.rs index 0d8d1a1e4e6..00e2d4a520d 100644 --- a/implementations/rust/ockam/ockam_node/src/metrics.rs +++ b/implementations/rust/ockam/ockam_node/src/metrics.rs @@ -3,27 +3,34 @@ use core::{ sync::atomic::{AtomicBool, AtomicUsize, Ordering}, time::Duration, }; -use ockam_core::compat::{collections::BTreeMap, sync::Arc}; +use ockam_core::compat::{collections::HashMap, sync::Arc}; use ockam_core::env::get_env; +use opentelemetry::trace::FutureExt; use std::{fs::OpenOptions, io::Write}; +use tokio::runtime::Handle; pub struct Metrics { - rt: Arc, + runtime_handle: Handle, router: (Arc, Arc), } impl Metrics { /// Create a new Metrics collector with access to the runtime pub(crate) fn new( - rt: &Arc, + runtime_handle: Handle, router: (Arc, Arc), ) -> Arc { Arc::new(Self { - rt: Arc::clone(rt), + runtime_handle, router, }) } + pub(crate) fn spawn(self: Arc, alive: Arc) { + self.runtime_handle + .spawn(self.run(alive).with_current_context()); + } + /// Spawned by the Executor to periodically collect metrics pub(crate) async fn run(self: Arc, alive: Arc) { let path = match get_env::("OCKAM_METRICS_PATH") { @@ -66,13 +73,13 @@ impl Metrics { freq: u64, acc: &mut MetricsReport, ) -> MetricsReport { - let m = self.rt.metrics(); + let m = self.runtime_handle.metrics(); let tokio_workers = m.num_workers(); let router_addr_count = self.router.0.load(Ordering::Acquire); let router_cluster_count = self.router.1.load(Ordering::Acquire); - let mut tokio_busy_ms = BTreeMap::new(); + let mut tokio_busy_ms = HashMap::new(); for wid in 0..tokio_workers { // Get the previously accumulated let acc_ms = acc.tokio_busy_ms.get(&wid).unwrap_or(&0); @@ -96,7 +103,7 @@ impl Metrics { #[derive(Default)] #[allow(unused)] pub struct MetricsReport { - tokio_busy_ms: BTreeMap, + tokio_busy_ms: HashMap, router_addr_count: usize, router_cluster_count: usize, } diff --git a/implementations/rust/ockam/ockam_node/src/node.rs b/implementations/rust/ockam/ockam_node/src/node.rs index 83ac54103e4..51e83487ce8 100644 --- a/implementations/rust/ockam/ockam_node/src/node.rs +++ b/implementations/rust/ockam/ockam_node/src/node.rs @@ -4,7 +4,6 @@ use ockam_core::compat::sync::Arc; use ockam_core::flow_control::FlowControls; #[cfg(feature = "std")] use ockam_core::OpenTelemetryContext; -use ockam_core::{Address, AllowAll, Mailbox, Mailboxes}; /// A minimal worker implementation that does nothing pub struct NullWorker; @@ -116,8 +115,6 @@ impl NodeBuilder { #[cfg(not(feature = "std"))] Arc::new(Runtime::new().expect("cannot initialize the tokio runtime")) }); - let exe = Executor::new(rt.clone(), &flow_controls); - let addr: Address = "app".into(); #[cfg(feature = "watchdog")] { @@ -125,17 +122,17 @@ impl NodeBuilder { watchdog.start_watchdog_loop(&rt); } + let handle = rt.handle().clone(); + let exe = Executor::new(rt, &flow_controls); + + let router = exe.router().upgrade().unwrap(); + // The root application worker needs a mailbox and relay to accept // messages from workers, and to buffer incoming transcoded data. - let (ctx, sender, _) = Context::new( - rt.handle().clone(), - exe.router(), - Mailboxes::new( - Mailbox::new(addr, Arc::new(AllowAll), Arc::new(AllowAll)), - vec![], - ), - None, - Default::default(), + + let (ctx, sender, _) = Context::create_app_context( + handle.clone(), + Arc::downgrade(&router), &flow_controls, #[cfg(feature = "std")] OpenTelemetryContext::current(), @@ -144,7 +141,14 @@ impl NodeBuilder { debugger::log_inherit_context("NODE", &ctx, &ctx); // Register this mailbox handle with the executor - exe.initialize_system("app", sender) + router + .add_worker( + ctx.mailboxes(), + sender, + true, + Default::default(), + ctx.mailbox_count(), + ) .expect("router initialization failed"); // Then return the root context and executor diff --git a/implementations/rust/ockam/ockam_node/src/processor_builder.rs b/implementations/rust/ockam/ockam_node/src/processor_builder.rs index 4edc3232cc4..0d01e1bb45c 100644 --- a/implementations/rust/ockam/ockam_node/src/processor_builder.rs +++ b/implementations/rust/ockam/ockam_node/src/processor_builder.rs @@ -1,9 +1,9 @@ -use crate::debugger; +use crate::{debugger, ContextMode, WorkerShutdownPriority}; use crate::{relay::ProcessorRelay, Context}; -use alloc::string::String; -use ockam_core::compat::{sync::Arc, vec::Vec}; +use ockam_core::compat::string::String; +use ockam_core::compat::sync::Arc; use ockam_core::{ - Address, AddressAndMetadata, AddressMetadata, DenyAll, IncomingAccessControl, Mailboxes, + Address, AddressMetadata, DenyAll, IncomingAccessControl, Mailbox, Mailboxes, OutgoingAccessControl, Processor, Result, }; @@ -32,14 +32,47 @@ impl

ProcessorBuilder

where P: Processor, { - /// Worker with only one [`Address`] + /// Processor with only one [`Address`] pub fn with_address(self, address: impl Into

) -> ProcessorBuilderOneAddress

{ + self.with_address_and_metadata_impl(address, None) + } + + /// Processor with single terminal [`Address`] + pub fn with_terminal_address( + self, + address: impl Into

, + ) -> ProcessorBuilderOneAddress

{ + self.with_address_and_metadata( + address, + AddressMetadata { + is_terminal: true, + attributes: vec![], + }, + ) + } + + /// Processor with single terminal [`Address`] and metadata + pub fn with_address_and_metadata( + self, + address: impl Into

, + metadata: AddressMetadata, + ) -> ProcessorBuilderOneAddress

{ + self.with_address_and_metadata_impl(address, Some(metadata)) + } + + /// Processor with single terminal [`Address`] and metadata + pub fn with_address_and_metadata_impl( + self, + address: impl Into

, + metadata: Option, + ) -> ProcessorBuilderOneAddress

{ ProcessorBuilderOneAddress { incoming_ac: Arc::new(DenyAll), outgoing_ac: Arc::new(DenyAll), processor: self.processor, address: address.into(), - metadata: None, + metadata, + shutdown_priority: Default::default(), } } @@ -47,8 +80,8 @@ where pub fn with_mailboxes(self, mailboxes: Mailboxes) -> ProcessorBuilderMultipleAddresses

{ ProcessorBuilderMultipleAddresses { mailboxes, + shutdown_priority: Default::default(), processor: self.processor, - metadata_list: vec![], } } } @@ -58,74 +91,28 @@ where P: Processor, { mailboxes: Mailboxes, + shutdown_priority: WorkerShutdownPriority, processor: P, - metadata_list: Vec, } impl

ProcessorBuilderMultipleAddresses

where P: Processor, { - /// Mark the provided address as terminal - pub fn terminal(self, address: impl Into

) -> Self { - self.terminal_with_attributes(address.into(), vec![]) + /// Consume this builder and start a new Ockam [`Processor`] from the given context + pub fn start(self, context: &Context) -> Result<()> { + start( + context, + self.mailboxes, + self.shutdown_priority, + self.processor, + ) } - /// Mark the provided address as terminal - pub fn terminal_with_attributes( - mut self, - address: impl Into
, - attributes: Vec<(String, String)>, - ) -> Self { - let address = address.into(); - let metadata = self.metadata_list.iter_mut().find(|m| m.address == address); - - if let Some(metadata) = metadata { - metadata.metadata.is_terminal = true; - metadata.metadata.attributes = attributes; - } else { - self.metadata_list.push(AddressAndMetadata { - address, - metadata: AddressMetadata { - is_terminal: true, - attributes, - }, - }); - } + pub fn with_shutdown_priority(mut self, shutdown_priority: WorkerShutdownPriority) -> Self { + self.shutdown_priority = shutdown_priority; self } - - /// Adds metadata attribute for the provided address - pub fn with_metadata_attribute( - mut self, - address: impl Into
, - key: impl Into, - value: impl Into, - ) -> Self { - let address = address.into(); - let metadata = self.metadata_list.iter_mut().find(|m| m.address == address); - - if let Some(metadata) = metadata { - metadata - .metadata - .attributes - .push((key.into(), value.into())); - } else { - self.metadata_list.push(AddressAndMetadata { - address, - metadata: AddressMetadata { - is_terminal: false, - attributes: vec![(key.into(), value.into())], - }, - }); - } - self - } - - /// Consume this builder and start a new Ockam [`Processor`] from the given context - pub async fn start(self, context: &Context) -> Result<()> { - start(context, self.mailboxes, self.processor, self.metadata_list).await - } } pub struct ProcessorBuilderOneAddress

@@ -136,67 +123,58 @@ where outgoing_ac: Arc, address: Address, processor: P, - metadata: Option, + metadata: Option, + shutdown_priority: WorkerShutdownPriority, } impl

ProcessorBuilderOneAddress

where P: Processor, { - /// Mark the address as terminal - pub fn terminal(self) -> Self { - self.terminal_with_attributes(vec![]) - } - - /// Mark the address as terminal - pub fn terminal_with_attributes(mut self, attributes: Vec<(String, String)>) -> Self { - if let Some(metadata) = self.metadata.as_mut() { - metadata.metadata.is_terminal = true; - metadata.metadata.attributes = attributes; - } else { - self.metadata = Some(AddressAndMetadata { - address: self.address.clone(), - metadata: AddressMetadata { - is_terminal: true, - attributes, - }, - }); - } + /// Mark the provided address as terminal + pub fn terminal(mut self) -> Self { + self.metadata + .get_or_insert(AddressMetadata { + is_terminal: false, + attributes: vec![], + }) + .is_terminal = true; self } - /// Adds metadata attribute + /// Adds metadata attribute for the provided address pub fn with_metadata_attribute( mut self, key: impl Into, value: impl Into, ) -> Self { - if let Some(metadata) = self.metadata.as_mut() { - metadata - .metadata - .attributes - .push((key.into(), value.into())); - } else { - self.metadata = Some(AddressAndMetadata { - address: self.address.clone(), - metadata: AddressMetadata { - is_terminal: false, - attributes: vec![(key.into(), value.into())], - }, - }); - } + self.metadata + .get_or_insert(AddressMetadata { + is_terminal: false, + attributes: vec![], + }) + .attributes + .push((key.into(), value.into())); + self } /// Consume this builder and start a new Ockam [`Processor`] from the given context - pub async fn start(self, context: &Context) -> Result<()> { + pub fn start(self, context: &Context) -> Result<()> { start( context, - Mailboxes::main(self.address, self.incoming_ac, self.outgoing_ac), + Mailboxes::new( + Mailbox::new( + self.address, + self.metadata, + self.incoming_ac, + self.outgoing_ac, + ), + vec![], + ), + self.shutdown_priority, self.processor, - self.metadata.map(|m| vec![m]).unwrap_or_default(), ) - .await } } @@ -239,35 +217,37 @@ where self.outgoing_ac = outgoing_access_control.clone(); self } + + pub fn with_shutdown_priority(mut self, shutdown_priority: WorkerShutdownPriority) -> Self { + self.shutdown_priority = shutdown_priority; + self + } } /// Consume this builder and start a new Ockam [`Processor`] from the given context - -pub async fn start

( +pub fn start

( context: &Context, mailboxes: Mailboxes, + shutdown_priority: WorkerShutdownPriority, processor: P, - metadata: Vec, ) -> Result<()> where P: Processor, { debug!( "Initializing ockam processor '{}' with access control in:{:?} out:{:?}", - mailboxes.main_address(), - mailboxes.main_mailbox().incoming_access_control(), - mailboxes.main_mailbox().outgoing_access_control(), + mailboxes.primary_address(), + mailboxes.primary_mailbox().incoming_access_control(), + mailboxes.primary_mailbox().outgoing_access_control(), ); - let addresses = mailboxes.addresses(); - // Pass it to the context - let (ctx, sender, ctrl_rx) = context.copy_with_mailboxes(mailboxes); + let (ctx, sender, ctrl_rx) = context.new_with_mailboxes(mailboxes, ContextMode::Attached); debugger::log_inherit_context("PROCESSOR", context, &ctx); - let router = context.router(); - router.start_processor(addresses, sender, metadata)?; + let router = context.router()?; + router.add_processor(ctx.mailboxes(), sender, shutdown_priority)?; // Then initialise the processor message relay ProcessorRelay::

::init(context.runtime(), processor, ctx, ctrl_rx); diff --git a/implementations/rust/ockam/ockam_node/src/relay/processor_relay.rs b/implementations/rust/ockam/ockam_node/src/relay/processor_relay.rs index 1a4e200a753..8169af1046c 100644 --- a/implementations/rust/ockam/ockam_node/src/relay/processor_relay.rs +++ b/implementations/rust/ockam/ockam_node/src/relay/processor_relay.rs @@ -1,4 +1,4 @@ -use crate::channel_types::SmallReceiver; +use crate::channel_types::OneshotReceiver; use crate::{relay::CtrlSignal, tokio::runtime::Handle, Context}; use ockam_core::{Processor, Result}; @@ -20,20 +20,19 @@ where #[cfg_attr(not(feature = "std"), allow(unused_mut))] #[cfg_attr(not(feature = "std"), allow(unused_variables))] - async fn run(self, mut ctrl_rx: SmallReceiver) { + async fn run(self, ctrl_rx: OneshotReceiver) { let mut ctx = self.ctx; let mut processor = self.processor; - let ctx_addr = ctx.address(); match processor.initialize(&mut ctx).await { Ok(()) => {} Err(e) => { error!( "Failure during '{}' processor initialisation: {}", - ctx.address(), + ctx.primary_address(), e ); - shutdown_and_stop_ack(&mut processor, &mut ctx, &ctx_addr).await; + shutdown_and_stop_ack(&mut processor, &mut ctx, false).await; return; } } @@ -51,10 +50,15 @@ where #[cfg(feature = "debugger")] error!( "Error encountered during '{}' processing: {:?}", - ctx_addr, e + ctx.primary_address(), + e ); #[cfg(not(feature = "debugger"))] - error!("Error encountered during '{}' processing: {}", ctx_addr, e); + error!( + "Error encountered during '{}' processing: {}", + ctx.primary_address(), + e + ); } } } @@ -62,15 +66,15 @@ where Result::<()>::Ok(()) }; + let mut stopped_from_router = false; #[cfg(feature = "std")] { - // This future resolves when a stop control signal is received - let shutdown_signal = async { ctrl_rx.recv().await }; - - // Then select over the two futures + // Select over the two futures tokio::select! { - _ = shutdown_signal => { - debug!("Shutting down processor {} due to shutdown signal", ctx_addr); + // This future resolves when a stop control signal is received + _ = ctrl_rx => { + debug!("Shutting down processor {} due to shutdown signal", ctx.primary_address()); + stopped_from_router = true; }, _ = run_loop => {} }; @@ -79,12 +83,12 @@ where // TODO wait on run_loop until we have a no_std select! implementation #[cfg(not(feature = "std"))] match run_loop.await { - Ok(_) => trace!("Processor shut down cleanly {}", ctx_addr), + Ok(_) => trace!("Processor shut down cleanly {}", ctx.primary_address()), Err(err) => error!("processor run loop aborted with error: {:?}", err), }; // If we reach this point the router has signaled us to shut down - shutdown_and_stop_ack(&mut processor, &mut ctx, &ctx_addr).await; + shutdown_and_stop_ack(&mut processor, &mut ctx, stopped_from_router).await; } /// Create a processor relay with two node contexts @@ -92,30 +96,56 @@ where rt: &Handle, processor: P, ctx: Context, - ctrl_rx: SmallReceiver, + ctrl_rx: OneshotReceiver, ) { let relay = ProcessorRelay::

::new(processor, ctx); rt.spawn(relay.run(ctrl_rx)); } } -async fn shutdown_and_stop_ack

( - processor: &mut P, - ctx: &mut Context, - ctx_addr: &ockam_core::Address, -) where +async fn shutdown_and_stop_ack

(processor: &mut P, ctx: &mut Context, stopped_from_router: bool) +where P: Processor, { match processor.shutdown(ctx).await { Ok(()) => {} Err(e) => { - error!("Failure during '{}' processor shutdown: {}", ctx_addr, e); + error!( + "Failure during '{}' processor shutdown: {}", + ctx.primary_address(), + e + ); + } + } + + let router = match ctx.router() { + Ok(router) => router, + Err(_) => { + error!( + "Failure during '{}' processor shutdown. Can't get router", + ctx.primary_address() + ); + return; + } + }; + + if !stopped_from_router { + if let Err(e) = router.stop_address(ctx.primary_address(), !stopped_from_router) { + error!( + "Failure during '{}' processor shutdown: {}", + ctx.primary_address(), + e + ); } } // Finally send the router a stop ACK -- log errors trace!("Sending shutdown ACK"); - ctx.stop_ack().await.unwrap_or_else(|e| { - error!("Failed to send stop ACK for '{}': {}", ctx_addr, e); + router.stop_ack(ctx.primary_address()).unwrap_or_else(|e| { + error!( + "Failed to send stop ACK for '{}': {}", + ctx.primary_address(), + e + ); }); } diff --git a/implementations/rust/ockam/ockam_node/src/relay/worker_relay.rs b/implementations/rust/ockam/ockam_node/src/relay/worker_relay.rs index 0d2aaa3adbb..fe3916f7770 100644 --- a/implementations/rust/ockam/ockam_node/src/relay/worker_relay.rs +++ b/implementations/rust/ockam/ockam_node/src/relay/worker_relay.rs @@ -1,4 +1,4 @@ -use crate::channel_types::SmallReceiver; +use crate::channel_types::OneshotReceiver; use crate::relay::CtrlSignal; use crate::tokio::runtime::Handle; use crate::Context; @@ -60,7 +60,7 @@ where let relay_msg = match self.ctx.receiver_next().await? { Some(msg) => msg, None => { - trace!("No more messages for worker {}", self.ctx.address()); + trace!("No more messages for worker {}", self.ctx.primary_address()); return Ok(false); } }; @@ -95,22 +95,20 @@ where #[cfg_attr(not(feature = "std"), allow(unused_mut))] #[cfg_attr(not(feature = "std"), allow(unused_variables))] - async fn run(mut self, mut ctrl_rx: SmallReceiver) { + async fn run(mut self, mut ctrl_rx: OneshotReceiver) { match self.worker.initialize(&mut self.ctx).await { Ok(()) => {} Err(e) => { error!( "Failure during '{}' worker initialisation: {}", - self.ctx.address(), + self.ctx.primary_address(), e ); - self.shutdown_and_stop_ack().await; + shutdown_and_stop_ack(&mut self.worker, &mut self.ctx, false).await; return; } } - let address = self.ctx.address(); - #[cfg(feature = "std")] loop { crate::tokio::select! { @@ -125,17 +123,15 @@ where // An error occurred -- log and continue Err(e) => { #[cfg(feature = "debugger")] - error!("Error encountered during '{}' message handling: {:?}", address, e); + error!("Error encountered during '{}' message handling: {:?}", self.ctx.primary_address(), e); #[cfg(not(feature = "debugger"))] - error!("Error encountered during '{}' message handling: {}", address, e); + error!("Error encountered during '{}' message handling: {}", self.ctx.primary_address(), e); } } }, - result = ctrl_rx.recv() => { - if result.is_some() { - debug!("Relay received shutdown signal, terminating!"); - break; - } + _ = &mut ctrl_rx => { + debug!(primary_address=%self.ctx.primary_address(), "Relay received shutdown signal, terminating!"); + break; // We are stopping } @@ -153,41 +149,69 @@ where // An error occurred -- log and continue Err(e) => error!( "Error encountered during '{}' message handling: {}", - address, e + self.ctx.primary_address(), + e ), } } - self.shutdown_and_stop_ack().await; + shutdown_and_stop_ack(&mut self.worker, &mut self.ctx, true).await; } - async fn shutdown_and_stop_ack(&mut self) { - // Run the shutdown hook for this worker - match self.worker.shutdown(&mut self.ctx).await { - Ok(()) => {} - Err(e) => { - error!( - "Failure during '{}' worker shutdown: {}", - self.ctx.address(), - e - ); - } - } + /// Build and spawn a new worker relay, returning a send handle to it + pub(crate) fn init(rt: &Handle, worker: W, ctx: Context, ctrl_rx: OneshotReceiver) { + let relay = WorkerRelay::new(worker, ctx); + rt.spawn(relay.run(ctrl_rx)); + } +} - // Finally send the router a stop ACK -- log errors - trace!("Sending shutdown ACK"); - self.ctx.stop_ack().await.unwrap_or_else(|e| { +async fn shutdown_and_stop_ack(worker: &mut W, ctx: &mut Context, stopped_from_router: bool) +where + W: Worker, +{ + // Run the shutdown hook for this worker + // TODO: pass stopped_from_router to the shutdown, a Worker may choose different strategy on + // shutting down dependent workers based on that. E.g., TcpSender should stop TcpReceiver if + // we close the TCP connection, but not if we shutdown the node. + match worker.shutdown(ctx).await { + Ok(()) => {} + Err(e) => { error!( - "Failed to send stop ACK for worker '{}': {}", - self.ctx.address(), + "Failure during '{}' worker shutdown: {}", + ctx.primary_address(), e - ) - }); + ); + } } - /// Build and spawn a new worker relay, returning a send handle to it - pub(crate) fn init(rt: &Handle, worker: W, ctx: Context, ctrl_rx: SmallReceiver) { - let relay = WorkerRelay::new(worker, ctx); - rt.spawn(relay.run(ctrl_rx)); + let router = match ctx.router() { + Ok(router) => router, + Err(_) => { + error!( + "Failure during '{}' worker shutdown. Can't get router", + ctx.primary_address() + ); + return; + } + }; + + if !stopped_from_router { + if let Err(e) = router.stop_address(ctx.primary_address(), !stopped_from_router) { + error!( + "Failure during '{}' worker shutdown: {}", + ctx.primary_address(), + e + ); + } } + + // Finally send the router a stop ACK -- log errors + trace!("Sending shutdown ACK"); + router.stop_ack(ctx.primary_address()).unwrap_or_else(|e| { + error!( + "Failed to send stop ACK for worker '{}': {}", + ctx.primary_address(), + e + ) + }); } diff --git a/implementations/rust/ockam/ockam_node/src/router/mod.rs b/implementations/rust/ockam/ockam_node/src/router/mod.rs index c04fe5220bc..171dab262b9 100644 --- a/implementations/rust/ockam/ockam_node/src/router/mod.rs +++ b/implementations/rust/ockam/ockam_node/src/router/mod.rs @@ -1,172 +1,8 @@ mod processor; mod record; +#[allow(clippy::module_inception)] +mod router; mod shutdown; -mod state; pub mod worker; -#[cfg(feature = "metrics")] -use core::sync::atomic::AtomicUsize; - -use crate::channel_types::{MessageSender, SmallSender}; -use crate::relay::CtrlSignal; -use crate::{NodeError, NodeReason}; -use alloc::string::String; -use alloc::sync::Arc; -use alloc::vec::Vec; -use ockam_core::compat::collections::BTreeMap; -use ockam_core::compat::sync::RwLock as SyncRwLock; -use ockam_core::errcode::{Kind, Origin}; -use ockam_core::flow_control::FlowControls; -use ockam_core::{ - Address, AddressAndMetadata, AddressMetadata, Error, RelayMessage, Result, TransportType, -}; -use record::{AddressRecord, InternalMap, WorkerMeta}; -use state::{NodeState, RouterState}; - -/// A pair of senders to a worker relay -#[derive(Debug)] -pub struct SenderPair { - pub msgs: MessageSender, - pub ctrl: SmallSender, -} - -/// A combined address type and local worker router -/// -/// This router supports two routing modes: internal, and external. -/// -/// Internal routing resolves `type=0` addresses to local workers. -/// -/// External routing is supported only after a plugin component -/// registers itself with this router. Only one router can be -/// registered per address type. -pub struct Router { - /// Keep track of some additional router state information - state: RouterState, - /// Internal address state - map: InternalMap, - /// Externally registered router components - external: SyncRwLock>, -} - -enum RouteType { - Internal, - External(TransportType), -} - -fn determine_type(next: &Address) -> RouteType { - if next.transport_type().is_local() { - RouteType::Internal - } else { - RouteType::External(next.transport_type()) - } -} - -impl Router { - pub fn new(flow_controls: &FlowControls) -> Self { - Self { - state: RouterState::new(), - map: InternalMap::new(flow_controls), - external: Default::default(), - } - } - - pub fn init(&self, addr: Address, senders: SenderPair) -> Result<()> { - self.map.insert_address_record( - addr.clone(), - AddressRecord::new( - vec![addr.clone()], - senders.msgs, - senders.ctrl, - Arc::new(0.into()), // don't track for app worker (yet?) - WorkerMeta { - processor: false, - detached: true, - }, - ), - vec![], - ) - } - - pub fn set_cluster(&self, addr: Address, label: String) -> Result<()> { - self.map.set_cluster(label, addr) - } - - pub fn list_workers(&self) -> Vec

{ - self.map.list_workers() - } - - pub fn is_worker_registered_at(&self, address: &Address) -> bool { - self.map.is_worker_registered_at(address) - } - - pub async fn stop_ack(&self, addr: Address) -> Result<()> { - let running = self.state.running(); - debug!(%running, "Handling shutdown ACK for {}", addr); - self.map.free_address(&addr); - - if !running { - // The router is shutting down - if !self.map.cluster_done() { - // We are not done yet. - // The last worker should call another `stop_ack` - return Ok(()); - } - - // Check if there is a next cluster - let finished = self.stop_next_cluster().await?; - if finished { - self.state.terminate().await; - } - } - Ok(()) - } - - pub fn find_terminal_address(&self, addresses: Vec
) -> Option { - self.map.find_terminal_address(&addresses) - } - - pub fn get_address_metadata(&self, address: &Address) -> Option { - self.map.get_address_metadata(address) - } - - pub fn register_router(&self, tt: TransportType, addr: Address) -> Result<()> { - let mut guard = self.external.write().unwrap(); - if let alloc::collections::btree_map::Entry::Vacant(e) = guard.entry(tt) { - e.insert(addr); - Ok(()) - } else { - // already exists - Err(Error::new( - Origin::Node, - Kind::AlreadyExists, - "Router already exists", - )) - } - } - - pub fn resolve(&self, addr: &Address) -> Result> { - let addr = match determine_type(addr) { - RouteType::Internal => addr, - // TODO: Remove after other transport implementations are moved to new architecture - RouteType::External(tt) => &self.address_for_transport(tt)?, - }; - self.map.resolve(addr) - } - - fn address_for_transport(&self, tt: TransportType) -> Result
{ - let guard = self.external.read().unwrap(); - guard - .get(&tt) - .cloned() - .ok_or_else(|| NodeError::NodeState(NodeReason::Unknown).internal()) - } - - pub async fn wait_termination(self: Arc) { - self.state.wait_termination().await; - } - - #[cfg(feature = "metrics")] - pub(crate) fn get_metrics_readout(&self) -> (Arc, Arc) { - self.map.get_metrics() - } -} +pub use router::*; diff --git a/implementations/rust/ockam/ockam_node/src/router/processor.rs b/implementations/rust/ockam/ockam_node/src/router/processor.rs index a06a72321d9..0a7182393d6 100644 --- a/implementations/rust/ockam/ockam_node/src/router/processor.rs +++ b/implementations/rust/ockam/ockam_node/src/router/processor.rs @@ -1,80 +1,58 @@ -use super::{AddressRecord, NodeState, Router, SenderPair, WorkerMeta}; -use crate::{error::NodeError, RouterReason}; -use ockam_core::compat::{sync::Arc, vec::Vec}; +use super::{Router, RouterState, SenderPair}; +use crate::router::record::{AddressRecord, WorkerMeta}; +use crate::WorkerShutdownPriority; +use ockam_core::compat::sync::Arc; use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{Address, AddressAndMetadata, Error, Result}; +use ockam_core::{Error, Mailboxes, Result}; impl Router { /// Start a processor - pub(crate) fn start_processor( + pub(crate) fn add_processor( &self, - addrs: Vec
, + mailboxes: &Mailboxes, senders: SenderPair, - addresses_metadata: Vec, + shutdown_priority: WorkerShutdownPriority, ) -> Result<()> { - if self.state.running() { - self.start_processor_impl(addrs, senders, addresses_metadata) - } else { - match self.state.node_state() { - NodeState::Stopping => Err(Error::new( - Origin::Node, - Kind::Shutdown, - "The node is shutting down", - ))?, - NodeState::Running => unreachable!(), - NodeState::Terminated => unreachable!(), - } + if *self.state.read().unwrap() != RouterState::Running { + return Err(Error::new( + Origin::Node, + Kind::Shutdown, + "The node is shutting down", + ))?; } + + self.add_processor_impl(mailboxes, senders, shutdown_priority) } - fn start_processor_impl( + fn add_processor_impl( &self, - addrs: Vec
, + mailboxes: &Mailboxes, senders: SenderPair, - addresses_metadata: Vec, + shutdown_priority: WorkerShutdownPriority, ) -> Result<()> { - let primary_addr = addrs - .first() - .ok_or_else(|| NodeError::RouterState(RouterReason::EmptyAddressSet).internal())?; - - debug!("Starting new processor '{}'", &primary_addr); + debug!("Starting new processor '{}'", mailboxes.primary_address()); let SenderPair { msgs, ctrl } = senders; let record = AddressRecord::new( - addrs.clone(), + mailboxes.primary_address().clone(), + mailboxes.additional_addresses().cloned().collect(), msgs, ctrl, + WorkerMeta { + processor: true, + detached: false, + }, + shutdown_priority, // We don't keep track of the mailbox count for processors // because, while they are able to send and receive messages // via their mailbox, most likely this metric is going to be // irrelevant. We may want to re-visit this decision in the // future, if the way processors are used changes. Arc::new(0.into()), - WorkerMeta { - processor: true, - detached: false, - }, ); - self.map - .insert_address_record(primary_addr.clone(), record, addresses_metadata) - } - - /// Stop the processor - pub(crate) async fn stop_processor(&self, addr: &Address) -> Result<()> { - trace!("Stopping processor '{}'", addr); - - // Resolve any secondary address to the primary address - let primary_address = match self.map.get_primary_address(addr) { - Some(p) => p.clone(), - None => { - return Err(Error::new(Origin::Node, Kind::NotFound, "No such address") - .context("Address", addr.clone())) - } - }; + self.map.insert_address_record(record, mailboxes)?; - // Then send processor shutdown signal - self.map.stop(&primary_address).await?; Ok(()) } } diff --git a/implementations/rust/ockam/ockam_node/src/router/record.rs b/implementations/rust/ockam/ockam_node/src/router/record.rs index 6aa197cf93b..7c12a9c0797 100644 --- a/implementations/rust/ockam/ockam_node/src/router/record.rs +++ b/implementations/rust/ockam/ockam_node/src/router/record.rs @@ -1,79 +1,85 @@ -use crate::channel_types::{MessageSender, SmallSender}; +use crate::channel_types::{oneshot_channel, MessageSender, OneshotReceiver, OneshotSender}; use crate::error::{NodeError, NodeReason}; use crate::relay::CtrlSignal; -use alloc::string::String; +use crate::WorkerShutdownPriority; use core::default::Default; use core::fmt::Debug; -use core::sync::atomic::{AtomicU8, AtomicUsize, Ordering}; +use core::sync::atomic::{AtomicUsize, Ordering}; +use ockam_core::compat::collections::hash_map::Entry; use ockam_core::compat::sync::Mutex as SyncMutex; use ockam_core::compat::sync::RwLock as SyncRwLock; -use ockam_core::compat::sync::RwLockWriteGuard as SyncRwLockWriteGuard; use ockam_core::errcode::{Kind, Origin}; use ockam_core::{ compat::{ - collections::{BTreeMap, BTreeSet}, + collections::{HashMap, HashSet}, sync::Arc, vec::Vec, }, flow_control::FlowControls, - Address, AddressAndMetadata, AddressMetadata, Error, RelayMessage, Result, + Address, AddressMetadata, Error, Mailbox, Mailboxes, RelayMessage, Result, }; #[derive(Default)] struct AddressMaps { + // NOTE: It's crucial that if more that one of these structures is needed to perform an + // operation, we should always acquire locks in the order they're declared here. Otherwise, it + // can cause a deadlock. /// Registry of primary address to worker address record state - address_records_map: BTreeMap, + records: SyncRwLock>, /// Alias-registry to map arbitrary address to primary addresses - alias_map: BTreeMap, + aliases: SyncRwLock>, /// Registry of arbitrary metadata for each address, lazily populated - address_metadata_map: BTreeMap, + metadata: SyncRwLock>, } /// Address states and associated logic pub struct InternalMap { - address_maps: SyncRwLock, - /// The order in which clusters are allocated and de-allocated - cluster_order: SyncMutex>, - /// Cluster data records - clusters: SyncMutex>>, - /// Track stop information for Clusters - stopping: SyncMutex>, + // NOTE: It's crucial that if more that one of these structures is needed to perform an + // operation, we should always acquire locks in the order they're declared here. Otherwise, it + // can cause a deadlock. + address_maps: AddressMaps, + /// Track non-detached addresses that are being stopped (except those that are stopped due to node shutdown) + stopping: SyncMutex>, + /// Track non-detached addresses that are being stopped due to node shutdown + stopping_shutdown: SyncMutex>, + /// Channel to notify when stopping_shutdown map gets empty + shutdown_yield_sender: SyncMutex>>, /// Access to [`FlowControls`] to clean resources flow_controls: FlowControls, /// Metrics collection and sharing #[cfg(feature = "metrics")] metrics: (Arc, Arc), } + impl InternalMap { pub(crate) fn resolve(&self, addr: &Address) -> Result> { - let guard = self.address_maps.read().unwrap(); + let records = self.address_maps.records.read().unwrap(); + let aliases = self.address_maps.aliases.read().unwrap(); - let address_record = if let Some(primary_address) = guard.alias_map.get(addr) { - guard.address_records_map.get(primary_address) + let address_record = if let Some(primary_address) = aliases.get(addr) { + records.get(primary_address) } else { - trace!("Resolving worker address '{addr}'... FAILED; no such worker"); - return Err(Error::new(Origin::Node, Kind::NotFound, "No such address") - .context("Address", addr.clone())); + trace!("Resolving worker address '{addr}'... FAILED; no such alias"); + return Err(Error::new( + Origin::Node, + Kind::NotFound, + format!("No such alias: {}", addr), + )); }; match address_record { Some(address_record) => { - if let Some(sender) = address_record.sender() { - trace!("Resolving worker address '{addr}'... OK"); - address_record.increment_msg_count(); - Ok(sender) - } else { - trace!("Resolving worker address '{addr}'... REJECTED; worker shutting down"); - Err( - Error::new(Origin::Node, Kind::Shutdown, "Worker shutting down") - .context("Address", addr.clone()), - ) - } + trace!("Resolving worker address '{addr}'... OK"); + address_record.increment_msg_count(); + Ok(address_record.sender.clone()) } None => { trace!("Resolving worker address '{addr}'... FAILED; no such worker"); - Err(Error::new(Origin::Node, Kind::NotFound, "No such address") - .context("Address", addr.clone())) + Err(Error::new( + Origin::Node, + Kind::NotFound, + format!("No such address: {}", addr), + )) } } } @@ -83,9 +89,9 @@ impl InternalMap { pub(super) fn new(flow_controls: &FlowControls) -> Self { Self { address_maps: Default::default(), - cluster_order: SyncMutex::new(Default::default()), - clusters: SyncMutex::new(Default::default()), - stopping: SyncMutex::new(Default::default()), + stopping: Default::default(), + stopping_shutdown: Default::default(), + shutdown_yield_sender: Default::default(), flow_controls: flow_controls.clone(), #[cfg(feature = "metrics")] metrics: Default::default(), @@ -94,57 +100,103 @@ impl InternalMap { } impl InternalMap { - #[cfg_attr(not(feature = "std"), allow(dead_code))] - pub(super) fn clear_address_records_map(&self) { - self.address_maps - .write() - .unwrap() - .address_records_map - .clear() + pub(super) fn stop(&self, address: &Address, skip_sending_stop_signal: bool) -> Result<()> { + // To guarantee consistency we'll first acquire lock on all the maps we need to touch + // and only then start modifications + let mut records = self.address_maps.records.write().unwrap(); + let mut aliases = self.address_maps.aliases.write().unwrap(); + let mut metadata = self.address_maps.metadata.write().unwrap(); + let mut stopping = self.stopping.lock().unwrap(); + + let primary_address = aliases + .get(address) + .ok_or_else(|| { + Error::new( + Origin::Node, + Kind::NotFound, + format!("No such alias: {}", address), + ) + })? + .clone(); + + self.flow_controls.cleanup_address(&primary_address); + + let record = if let Some(record) = records.remove(&primary_address) { + record + } else { + return Err(Error::new( + Origin::Node, + Kind::NotFound, + format!("No such address: {}", primary_address), + )); + }; + + for address in &record.additional_addresses { + metadata.remove(address); + aliases.remove(address); + } + + metadata.remove(&primary_address); + aliases.remove(&primary_address); + + // Detached doesn't need any stop confirmation, since they don't have a Relay = don't have + // an async task running in a background that should be stopped. + if !record.meta.detached { + let res = stopping.insert(primary_address); + debug!( + "Inserted {} into stopping. Inserted = {}", + record.primary_address, res + ); + } + + record.stop(skip_sending_stop_signal)?; + + Ok(()) } - pub(super) async fn stop(&self, primary_address: &Address) -> Result<()> { + pub(super) fn stop_ack(&self, primary_address: &Address) { { - let mut guard = self.stopping.lock().unwrap(); - if guard.contains(primary_address) { - return Ok(()); - } else { - guard.insert(primary_address.clone()); - } + let mut stopping = self.stopping.lock().unwrap(); + let res = stopping.remove(primary_address); + + debug!( + "Removing {} from stopping. Removed = {}", + primary_address, res + ); } - let send_signal_future = { - let guard = self.address_maps.read().unwrap(); - if let Some(record) = guard.address_records_map.get(primary_address) { - record.stop() - } else { - return Err(Error::new(Origin::Node, Kind::NotFound, "No such address") - .context("Address", primary_address.clone())); - } - }; + let mut stopping_shutdown = self.stopping_shutdown.lock().unwrap(); - // we can't call `.await` while holding the lock - if let Some(send_signal_future) = send_signal_future { - send_signal_future.await - } else { - Ok(()) + let res = stopping_shutdown.remove(primary_address); + debug!( + "Removing {} from stopping_shutdown. Removed = {}", + primary_address, res + ); + + if stopping_shutdown.is_empty() { + if let Some(shutdown_yield_sender) = self.shutdown_yield_sender.lock().unwrap().take() { + debug!("Sending stop_ack signal"); + if shutdown_yield_sender.send(()).is_err() { + warn!("shutdown_yield send errored"); + } + } } } pub(super) fn is_worker_registered_at(&self, primary_address: &Address) -> bool { self.address_maps + .records .read() .unwrap() - .address_records_map .contains_key(primary_address) // TODO: we should also check aliases } pub(super) fn list_workers(&self) -> Vec
{ self.address_maps + .records .read() .unwrap() - .address_records_map .keys() .cloned() .collect() @@ -152,103 +204,127 @@ impl InternalMap { pub(super) fn insert_address_record( &self, - primary_address: Address, record: AddressRecord, - addresses_metadata: Vec, + mailboxes: &Mailboxes, ) -> Result<()> { - let mut guard = self.address_maps.write().unwrap(); + let mut records = self.address_maps.records.write().unwrap(); - // check if the address already exists - if let Some(record) = guard.address_records_map.get(&primary_address) { - if record.check_integrity() { - let node = NodeError::Address(primary_address.clone()); + let entry = records.entry(record.primary_address.clone()); + + let entry = match entry { + Entry::Occupied(_) => { + let node = NodeError::Address(record.primary_address); return Err(node.already_exists()); - } else { - self.free_address_impl(&mut guard, &primary_address); + } + Entry::Vacant(entry) => entry, + }; + + // It may fail, so we don't insert record before that + Self::insert_aliases(&mut self.address_maps.aliases.write().unwrap(), &record)?; + Self::insert_all_metadata(&mut self.address_maps.metadata.write().unwrap(), mailboxes); + + entry.insert(record); + + Ok(()) + } + + fn insert_aliases( + aliases: &mut HashMap, + record: &AddressRecord, + ) -> Result<()> { + Self::insert_alias(aliases, &record.primary_address, &record.primary_address)?; + + for i in 0..record.additional_addresses.len() { + match Self::insert_alias( + aliases, + &record.primary_address, + &record.additional_addresses[i], + ) { + Ok(_) => {} + Err(err) => { + // Rollback + for j in 0..i { + aliases.remove(&record.additional_addresses[j]); + } + + return Err(err); + } } } - // check if aliases are already in use - for addr in record.address_set() { - if guard.alias_map.contains_key(addr) { + Ok(()) + } + + fn insert_alias( + aliases: &mut HashMap, + primary_address: &Address, + alias: &Address, + ) -> Result<()> { + match aliases.insert(alias.clone(), primary_address.clone()) { + None => Ok(()), + Some(old_value) => { + // Rollback + aliases.insert(alias.clone(), old_value); + let node = NodeError::Address(primary_address.clone()); - return Err(node.already_exists()); + Err(node.already_exists()) } } + } - record.address_set.iter().for_each(|addr| { - guard - .alias_map - .insert(addr.clone(), primary_address.clone()); - }); - - for metadata in addresses_metadata { - if !record.address_set().contains(&metadata.address) { - warn!( - "Address {} is not in the set of addresses", - metadata.address - ); - continue; - } + fn insert_all_metadata( + metadata: &mut HashMap, + mailboxes: &Mailboxes, + ) { + Self::insert_mailbox_metadata(metadata, mailboxes.primary_mailbox()); - let entry = guard - .address_metadata_map - .entry(metadata.address) - .or_default(); - *entry = metadata.metadata; + for mailbox in mailboxes.additional_mailboxes() { + Self::insert_mailbox_metadata(metadata, mailbox); } + } - _ = guard.address_records_map.insert(primary_address, record); - Ok(()) + fn insert_mailbox_metadata( + metadata: &mut HashMap, + mailbox: &Mailbox, + ) { + if let Some(meta) = mailbox.metadata().clone() { + metadata.insert(mailbox.address().clone(), meta.clone()); + } } - pub(super) fn find_terminal_address( + pub(super) fn find_terminal_address<'a>( &self, - addresses: &[Address], - ) -> Option { - addresses.iter().find_map(|address| { - self.address_maps - .read() - .unwrap() - .address_metadata_map - .get(address) - .filter(|&meta| meta.is_terminal) - .map(|meta| AddressAndMetadata { - address: address.clone(), - metadata: meta.clone(), - }) - }) + addresses: impl Iterator, + ) -> Option<(&'a Address, AddressMetadata)> { + let metadata = self.address_maps.metadata.read().unwrap(); + for address in addresses { + if let Some(metadata) = metadata.get(address) { + if metadata.is_terminal { + return Some((address, metadata.clone())); + } + } + } + + None } pub(super) fn get_address_metadata(&self, address: &Address) -> Option { self.address_maps + .metadata .read() .unwrap() - .address_metadata_map .get(address) .cloned() } - - pub(super) fn get_primary_address(&self, alias_address: &Address) -> Option
{ - self.address_maps - .read() - .unwrap() - .alias_map - .get(alias_address) - .cloned() - } } impl InternalMap { #[cfg(feature = "metrics")] pub(super) fn update_metrics(&self) { self.metrics.0.store( - self.address_maps.read().unwrap().address_records_map.len(), + self.address_maps.records.read().unwrap().len(), Ordering::Release, ); - self.metrics - .1 - .store(self.clusters.lock().unwrap().len(), Ordering::Release); } #[cfg(feature = "metrics")] @@ -261,172 +337,91 @@ impl InternalMap { self.metrics.0.load(Ordering::Acquire) } - /// Add an address to a particular cluster - pub(super) fn set_cluster(&self, label: String, primary: Address) -> Result<()> { - let address_records_guard = self.address_maps.read().unwrap(); - let rec = address_records_guard - .address_records_map - .get(&primary) - .ok_or_else(|| NodeError::Address(primary).not_found())?; - - let mut clusters_guard = self.clusters.lock().unwrap(); + /// Stop all workers with given priority + pub(super) fn stop_workers( + &self, + shutdown_priority: WorkerShutdownPriority, + ) -> Option> { + let records_to_stop: Vec = { + let mut records = self.address_maps.records.write().unwrap(); + + // we remove address records, so workers to be stopped can no longer be found, therefore + // can't be used to send messages + records + .extract_if(|_addr, record| record.shutdown_order == shutdown_priority) + .map(|(_addr, record)| record) + .collect() + }; - // If this is the first time we see this cluster ID - if !clusters_guard.contains_key(&label) { - clusters_guard.insert(label.clone(), BTreeSet::new()); - self.cluster_order.lock().unwrap().push(label.clone()); - } + let mut stopping_shutdown = self.stopping_shutdown.lock().unwrap(); - // Add all addresses to the cluster set - for addr in rec.address_set() { - clusters_guard - .get_mut(&label) - .expect("No such cluster??") - .insert(addr.clone()); + if !stopping_shutdown.is_empty() { + warn!( + "stopping_shutdown map is not empty, while next priority is about to be stopped. Clearing. Current priority: {:?}", shutdown_priority + ); + stopping_shutdown.clear(); } - Ok(()) - } - - /// Retrieve the next cluster in reverse-initialisation order - /// Return None if there is no next cluster or if the cluster - /// contained no more active addresses - pub(super) fn next_cluster(&self) -> Option> { - // loop until either: - // - there are no more clusters - // - we found a non-empty list of active addresses in a cluster - loop { - let name = self.cluster_order.lock().unwrap().pop()?; - let addrs = self.clusters.lock().unwrap().remove(&name)?; - let active_addresses: Vec
= self - .address_maps - .read() - .unwrap() - .address_records_map - .iter() - .filter_map(|(primary, _)| { - if addrs.contains(primary) { - Some(primary.clone()) - } else { - None - } - }) - .collect(); - if active_addresses.is_empty() { - continue; - } else { - return Some(active_addresses); + for record in records_to_stop { + // Detached doesn't need any stop confirmation, since they don't have a Relay => they + // don't have an async task running in a background that should be stopped. + let primary_address = record.primary_address.clone(); + if !record.meta.detached { + debug!("Inserted {} into stopping_shutdown", record.primary_address); + stopping_shutdown.insert(primary_address.clone()); } - } - } - - /// Mark this address as "having started to stop" - pub(super) fn init_stop(&self, addr: Address) { - self.stopping.lock().unwrap().insert(addr); - } - - /// Check whether the current cluster of addresses was stopped - pub(super) fn cluster_done(&self) -> bool { - self.stopping.lock().unwrap().is_empty() - } - /// Stop all workers not in a cluster, returns their primary addresses - pub(super) async fn stop_all_non_cluster_workers(&self) -> Vec
{ - let mut futures = Vec::new(); - let mut addresses = Vec::new(); - { - let clustered = - self.clusters - .lock() - .unwrap() - .iter() - .fold(BTreeSet::new(), |mut acc, (_, set)| { - acc.append(&mut set.clone()); - acc - }); - - let guard = self.address_maps.read().unwrap(); - let records: Vec<&AddressRecord> = guard - .address_records_map - .iter() - .filter_map(|(addr, rec)| { - if clustered.contains(addr) { - None - } else { - Some(rec) - } - }) - // Filter all detached workers because they don't matter :( - .filter(|rec| !rec.meta.detached) - .collect(); - - for record in records { - if let Some(first_address) = record.address_set.first() { - debug!("Stopping address {}", first_address); - addresses.push(first_address.clone()); - let send_stop_signal_future = record.stop(); - if let Some(send_stop_signal_future) = send_stop_signal_future { - futures.push((first_address.clone(), send_stop_signal_future)); - } - } else { - error!("Empty Address Set during graceful shutdown") - } + if let Err(err) = record.stop(false) { + error!("Error stopping address. Err={}", err); + // Let's not expect stop_ack from that worker in this case + stopping_shutdown.remove(&primary_address); } } - // We can only call `.await` outside the lock - for (first_address, send_stop_signal_future) in futures { - send_stop_signal_future.await.unwrap_or_else(|e| { - error!("Failed to stop address {}: {}", first_address, e); - }); - } + if !stopping_shutdown.is_empty() { + // If we just stopped some non-detached workers, let's wait for stop_ack form all of them + let (shutdown_yield_sender, shutdown_yield_receiver) = oneshot_channel(); - addresses - } + *self.shutdown_yield_sender.lock().unwrap() = Some(shutdown_yield_sender); - /// Permanently free all remaining resources associated to a particular address - pub(super) fn free_address(&self, primary: &Address) { - let mut guard = self.address_maps.write().unwrap(); - self.free_address_impl(&mut guard, primary); + Some(shutdown_yield_receiver) + } else { + None + } } - fn free_address_impl(&self, guard: &mut SyncRwLockWriteGuard, primary: &Address) { - self.stopping.lock().unwrap().remove(primary); - self.flow_controls.cleanup_address(primary); + pub(super) fn force_clear_records(&self) -> Vec
{ + let mut records = self.address_maps.records.write().unwrap(); - let removed = guard.address_records_map.remove(primary); - if let Some(record) = removed { - for alias_address in record.address_set { - guard.address_metadata_map.remove(&alias_address); - guard.alias_map.remove(&alias_address); - } - } + records.drain().map(|(address, _record)| address).collect() } } /// Additional metadata for worker records #[derive(Debug)] pub struct WorkerMeta { + #[allow(dead_code)] pub processor: bool, pub detached: bool, } pub struct AddressRecord { - address_set: Vec
, - sender: SyncMutex>>, - ctrl_tx: SmallSender, // Unused for not-detached workers - state: AtomicU8, + primary_address: Address, + additional_addresses: Vec
, + sender: MessageSender, + ctrl_tx: OneshotSender, meta: WorkerMeta, + shutdown_order: WorkerShutdownPriority, msg_count: Arc, } impl Debug for AddressRecord { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("AddressRecord") - .field("address_set", &self.address_set) - .field("sender", &self.sender.lock().unwrap().is_some()) + .field("primary_address", &self.primary_address) + .field("additional_addresses", &self.additional_addresses) + .field("sender", &self.sender) .field("ctrl_tx", &self.ctrl_tx) - .field("state", &self.state) .field("meta", &self.meta) .field("msg_count", &self.msg_count) .finish() @@ -434,32 +429,23 @@ impl Debug for AddressRecord { } impl AddressRecord { - pub fn address_set(&self) -> &[Address] { - &self.address_set - } - - pub fn sender(&self) -> Option> { - self.sender.lock().unwrap().clone() - } - - pub fn drop_sender(&self) { - *self.sender.lock().unwrap() = None; - } - pub fn new( - address_set: Vec
, + primary_address: Address, + additional_addresses: Vec
, sender: MessageSender, - ctrl_tx: SmallSender, - msg_count: Arc, + ctrl_tx: OneshotSender, meta: WorkerMeta, + shutdown_order: WorkerShutdownPriority, + msg_count: Arc, ) -> Self { AddressRecord { - address_set, - sender: SyncMutex::new(Some(sender)), + primary_address, + additional_addresses, + sender, ctrl_tx, - state: AtomicU8::new(AddressState::Running as u8), - msg_count, meta, + shutdown_order, + msg_count, } } @@ -469,118 +455,15 @@ impl AddressRecord { } /// Signal this worker to stop -- it will no longer be able to receive messages - /// Since the worker is held behind a lock, we cannot hold the synchronous lock - /// and call an `.await` to send the signal. - /// To avoid this shortcoming, we return a future that can be awaited on instead. - pub fn stop(&self) -> Option>> { - if self.state.load(Ordering::Relaxed) != AddressState::Running as u8 { - return None; - } + pub fn stop(self, skip_sending_stop_signal: bool) -> Result<()> { + trace!("AddressRecord::stop called for {:?}", self.primary_address); - // the stop can be triggered only once - let result = self.state.compare_exchange( - AddressState::Running as u8, - AddressState::Stopping as u8, - Ordering::Relaxed, - Ordering::Relaxed, - ); - if result.is_err() { - return None; + if !self.meta.detached && !skip_sending_stop_signal { + self.ctrl_tx + .send(CtrlSignal::InterruptStop) + .map_err(|_| NodeError::NodeState(NodeReason::Unknown).internal())?; } - if self.meta.processor { - let ctrl_tx = self.ctrl_tx.clone(); - Some(async move { - ctrl_tx - .send(CtrlSignal::InterruptStop) - .await - .map_err(|_| NodeError::NodeState(NodeReason::Unknown).internal())?; - Ok(()) - }) - } else { - self.drop_sender(); - None - } - } - - /// Check the integrity of this record - #[inline] - pub fn check_integrity(&self) -> bool { - self.state.load(Ordering::Relaxed) == AddressState::Running as u8 - && self.sender.lock().unwrap().is_some() - } -} - -/// Encode the run states a worker or processor can be in -#[repr(u8)] -#[derive(Debug, PartialEq, Eq)] -pub enum AddressState { - /// The runner is looping in its main body (either handling messages or a manual run-loop) - Running, - /// The runner was signaled to shut-down (running `shutdown()`) - Stopping, - /// The runner has experienced an error and is waiting for supervisor intervention - #[allow(unused)] - Faulty, -} - -#[cfg(test)] -mod test { - use super::*; - use crate::channel_types::small_channel; - use crate::router::record::InternalMap; - - #[test] - fn test_next_cluster() { - let map = InternalMap::new(&FlowControls::new()); - - // create 3 clusters - // cluster 1 has one active address - // cluster 2 has no active address - // cluster 3 has one active address - map.address_maps - .write() - .unwrap() - .address_records_map - .insert("address1".into(), create_address_record("address1")); - let _ = map.set_cluster("CLUSTER1".into(), "address1".into()); - - map.address_maps - .write() - .unwrap() - .address_records_map - .insert("address2".into(), create_address_record("address2")); - let _ = map.set_cluster("CLUSTER2".into(), "address2".into()); - map.free_address(&"address2".into()); - - map.address_maps - .write() - .unwrap() - .address_records_map - .insert("address3".into(), create_address_record("address3")); - let _ = map.set_cluster("CLUSTER3".into(), "address3".into()); - - // get the active addresses for cluster 3, clusters are popped in reverse order - assert_eq!(map.next_cluster(), Some(vec!["address3".into()])); - // get the active addresses for cluster 1, cluster 2 is skipped - assert_eq!(map.next_cluster(), Some(vec!["address1".into()])); - // finally there are no more clusters with active addresses - assert_eq!(map.next_cluster(), None); - } - - /// HELPERS - fn create_address_record(primary: &str) -> AddressRecord { - let (tx1, _) = small_channel(); - let (tx2, _) = small_channel(); - AddressRecord::new( - vec![primary.into()], - tx1, - tx2, - Arc::new(AtomicUsize::new(1)), - WorkerMeta { - processor: false, - detached: false, - }, - ) + Ok(()) } } diff --git a/implementations/rust/ockam/ockam_node/src/router/router.rs b/implementations/rust/ockam/ockam_node/src/router/router.rs new file mode 100644 index 00000000000..43e015459c5 --- /dev/null +++ b/implementations/rust/ockam/ockam_node/src/router/router.rs @@ -0,0 +1,168 @@ +#[cfg(feature = "metrics")] +use core::sync::atomic::AtomicUsize; + +use super::record::InternalMap; +use crate::channel_types::{MessageSender, OneshotSender}; +use crate::relay::CtrlSignal; +use crate::{NodeError, NodeReason}; +use alloc::vec::Vec; +use ockam_core::compat::collections::hash_map::Entry; +use ockam_core::compat::collections::HashMap; +use ockam_core::compat::sync::RwLock as SyncRwLock; +use ockam_core::errcode::{Kind, Origin}; +use ockam_core::flow_control::FlowControls; +use ockam_core::{Address, AddressMetadata, Error, RelayMessage, Result, TransportType}; + +/// A pair of senders to a worker relay +#[derive(Debug)] +pub struct SenderPair { + pub msgs: MessageSender, + pub ctrl: OneshotSender, +} + +enum RouteType { + Internal, + External(TransportType), +} + +fn determine_type(next: &Address) -> RouteType { + if next.transport_type().is_local() { + RouteType::Internal + } else { + RouteType::External(next.transport_type()) + } +} + +/// A combined address type and local worker router +/// +/// This router supports two routing modes: internal, and external. +/// +/// Internal routing resolves `type=0` addresses to local workers. +/// +/// External routing is supported only after a plugin component +/// registers itself with this router. Only one router can be +/// registered per address type. +pub struct Router { + /// Keep track of some additional router state information + pub(super) state: SyncRwLock, + /// Internal address state + pub(super) map: InternalMap, + /// Externally registered router components + pub(super) external: SyncRwLock>, + #[cfg(feature = "std")] + pub(super) shutdown_broadcast_sender: SyncRwLock>>, +} + +/// Node state +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum RouterState { + Running, + ShuttingDown, + Shutdown, +} + +impl Router { + pub fn new(flow_controls: &FlowControls) -> Self { + #[cfg(feature = "std")] + let (shutdown_broadcast_sender, _) = tokio::sync::broadcast::channel(1); + + Self { + state: RouterState::Running.into(), + map: InternalMap::new(flow_controls), + external: Default::default(), + #[cfg(feature = "std")] + shutdown_broadcast_sender: SyncRwLock::new(Some(shutdown_broadcast_sender)), + } + } + + pub fn list_workers(&self) -> Vec
{ + self.map.list_workers() + } + + pub fn is_worker_registered_at(&self, address: &Address) -> bool { + self.map.is_worker_registered_at(address) + } + + pub fn stop_ack(&self, primary_address: &Address) -> Result<()> { + debug!("Handling shutdown ACK for {}", primary_address); + + self.map.stop_ack(primary_address); + + Ok(()) + } + + pub fn find_terminal_address<'a>( + &self, + addresses: impl Iterator, + ) -> Option<(&'a Address, AddressMetadata)> { + self.map.find_terminal_address(addresses) + } + + pub fn get_address_metadata(&self, address: &Address) -> Option { + self.map.get_address_metadata(address) + } + + pub fn register_router(&self, tt: TransportType, addr: Address) -> Result<()> { + if let Entry::Vacant(e) = self.external.write().unwrap().entry(tt) { + e.insert(addr); + Ok(()) + } else { + // already exists + Err(Error::new( + Origin::Node, + Kind::AlreadyExists, + "Router already exists", + )) + } + } + + pub fn resolve(&self, addr: &Address) -> Result> { + let addr = match determine_type(addr) { + RouteType::Internal => addr, + // TODO: Remove after other transport implementations are moved to new architecture + RouteType::External(tt) => &self.address_for_transport(tt)?, + }; + self.map.resolve(addr) + } + + fn address_for_transport(&self, tt: TransportType) -> Result
{ + let guard = self.external.read().unwrap(); + guard + .get(&tt) + .cloned() + .ok_or_else(|| NodeError::NodeState(NodeReason::Unknown).internal()) + } + + /// Stop the worker + pub fn stop_address(&self, addr: &Address, skip_sending_stop_signal: bool) -> Result<()> { + debug!("Stopping address '{}'", addr); + + self.map.stop(addr, skip_sending_stop_signal)?; + + Ok(()) + } + + #[cfg(feature = "std")] + pub async fn wait_termination(&self) { + let mut receiver = match self.shutdown_broadcast_sender.read().unwrap().as_ref() { + None => { + // That's fine, means we already stopped + debug!("Waiting for termination but channel is missing"); + return; + } + Some(sender) => sender.subscribe(), + }; + + if let Err(err) = receiver.recv().await { + warn!("Waiting for termination errored: {}", err); + } + } + + #[cfg(not(feature = "std"))] + pub async fn wait_termination(&self) {} + + #[cfg(feature = "metrics")] + pub(crate) fn get_metrics_readout(&self) -> (Arc, Arc) { + self.map.get_metrics() + } +} diff --git a/implementations/rust/ockam/ockam_node/src/router/shutdown.rs b/implementations/rust/ockam/ockam_node/src/router/shutdown.rs index bccf02eba45..5492ccff155 100644 --- a/implementations/rust/ockam/ockam_node/src/router/shutdown.rs +++ b/implementations/rust/ockam/ockam_node/src/router/shutdown.rs @@ -1,81 +1,123 @@ -use super::Router; -use alloc::sync::Arc; -use alloc::vec::Vec; -use ockam_core::{Address, Result}; - -/// Register a stop ACK -/// -/// For every ACK we re-test whether the current cluster has stopped. -/// If not, we do nothing. If so, we trigger the next cluster to stop. +use super::{Router, RouterState}; +use crate::tokio::time; +use crate::WorkerShutdownPriority; +use core::time::Duration; +use ockam_core::compat::sync::Arc; +use ockam_core::Result; impl Router { /// Implement the graceful shutdown strategy #[cfg_attr(not(feature = "std"), allow(unused_variables))] - pub async fn stop_graceful(self: Arc, seconds: u8) -> Result<()> { - // Mark the router as shutting down to prevent spawning - info!("Initiate graceful node shutdown"); + pub async fn shutdown_graceful(self: Arc, seconds: u8) -> Result<()> { // This changes the router state to `Stopping` - let receiver = self.state.shutdown(); - let mut receiver = if let Some(receiver) = receiver { - receiver - } else { - debug!("Node is already terminated"); - return Ok(()); - }; + let state = { + let mut state = self.state.write().unwrap(); - // Start by shutting down clusterless workers - let cluster = self.map.stop_all_non_cluster_workers().await; + let state_val = *state; + if state_val == RouterState::Running { + *state = RouterState::ShuttingDown; + } - // If there _are_ no clusterless workers we go to the next cluster - if cluster.is_empty() { - let result = self.stop_next_cluster().await; - if let Ok(true) = result { - self.state.terminate().await; + state_val + }; + + match state { + RouterState::Running => {} + RouterState::ShuttingDown => { + info!("Router is already stopping"); + self.wait_termination().await; + return Ok(()); + } + RouterState::Shutdown => { + info!("Router is already stopped"); return Ok(()); } } - // Otherwise: keep track of addresses we are stopping - cluster - .into_iter() - .for_each(|addr| self.map.init_stop(addr)); + info!("Initiate graceful node shutdown"); // Start a timeout task to interrupt us... - #[cfg(feature = "std")] - { - use core::time::Duration; - use tokio::{task, time}; - - let dur = Duration::from_secs(seconds as u64); - task::spawn(async move { - time::sleep(dur).await; - warn!("Shutdown timeout reached; aborting node!"); - self.map.clear_address_records_map(); - self.state.terminate().await; - }); - } + let dur = Duration::from_secs(seconds as u64); - receiver.recv().await; - Ok(()) - } + let r = self.clone(); + let timeout = async move { + time::sleep(dur).await; + + // TODO: This actually doesn't abort anything, but it should unblock the .stop call, so + // that we can process and eventually drop the tokio Runtime + warn!("Shutdown timeout reached; aborting node!"); + let uncleared_addresses = r.map.force_clear_records(); - pub(crate) async fn stop_next_cluster(&self) -> Result { - let next_cluster_addresses = self.map.next_cluster(); + if !uncleared_addresses.is_empty() { + error!( + "Router internal inconsistency detected.\ + Records map is not empty after stopping all workers. Addresses: {:?}", + uncleared_addresses + ); + } + }; - match next_cluster_addresses { - Some(vec) => { - self.stop_cluster_addresses(vec).await?; - Ok(false) + let r = self.clone(); + let shutdown = async move { + for shutdown_priority in WorkerShutdownPriority::all_descending_order() { + debug!("Stopping workers with priority: {:?}", shutdown_priority); + let shutdown_yield_receiver = r.map.stop_workers(shutdown_priority); + + if let Some(shutdown_yield_receiver) = shutdown_yield_receiver { + debug!( + "Waiting for yield for workers with priority: {:?}", + shutdown_priority + ); + // Wait for stop ack + match shutdown_yield_receiver.await { + Ok(_) => { + debug!( + "Received yield for workers with priority: {:?}", + shutdown_priority + ); + } + Err(err) => { + error!("Error receiving shutdown yield: {}", err); + } + } + } else { + debug!( + "There was no workers with priority: {:?}", + shutdown_priority + ); + } } - // If not, we are done! - None => Ok(true), + + debug!("Router shutdown finished"); + }; + + #[cfg(feature = "std")] + crate::tokio::select! { + _ = shutdown => {} + _ = timeout => {} } - } - async fn stop_cluster_addresses(&self, addresses: Vec
) -> Result<()> { - for address in addresses.iter() { - self.map.stop(address).await?; + #[cfg(not(feature = "std"))] + shutdown.await; + + debug!("Setting Router state to Shutdown"); + *self.state.write().unwrap() = RouterState::Shutdown; + debug!("Sending Router shutdown broadcast"); + #[cfg(feature = "std")] + match self.shutdown_broadcast_sender.write().unwrap().take() { + None => { + warn!("Couldn't send Router shutdown message. Channel is missing."); + } + Some(shutdown_broadcast_sender) => { + if shutdown_broadcast_sender.send(()).is_err() { + // That's fine, it's possible nobody is listening for that broadcast + debug!("Couldn't send Router shutdown message. Sending error."); + } + } } + + info!("No more workers left. Goodbye!"); + Ok(()) } } diff --git a/implementations/rust/ockam/ockam_node/src/router/state.rs b/implementations/rust/ockam/ockam_node/src/router/state.rs deleted file mode 100644 index c36637f6b20..00000000000 --- a/implementations/rust/ockam/ockam_node/src/router/state.rs +++ /dev/null @@ -1,104 +0,0 @@ -//! Router run state utilities -use crate::channel_types::{SmallReceiver, SmallSender}; -use alloc::vec::Vec; -use core::ops::{Deref, DerefMut}; -use core::sync::atomic::AtomicBool; -use ockam_core::compat::sync::Mutex as SyncMutex; - -/// Node state -#[derive(Clone)] -pub enum NodeState { - Running, - Stopping, - Terminated, -} - -pub struct RouterState { - node_state: SyncMutex, - termination_senders: SyncMutex>>, - is_running: AtomicBool, -} - -impl RouterState { - pub fn new() -> Self { - Self { - node_state: SyncMutex::new(NodeState::Running), - termination_senders: SyncMutex::new(Default::default()), - is_running: AtomicBool::new(true), - } - } - - /// Set the router state to `Stopping` and return a receiver - /// to wait for the shutdown to complete. - /// When `None` is returned, the router is already terminated. - pub(super) fn shutdown(&self) -> Option> { - let mut guard = self.node_state.lock().unwrap(); - match guard.deref_mut() { - NodeState::Running => { - let (sender, receiver) = crate::channel_types::small_channel(); - *guard = NodeState::Stopping; - self.is_running - .store(false, core::sync::atomic::Ordering::Relaxed); - self.termination_senders.lock().unwrap().push(sender); - Some(receiver) - } - NodeState::Stopping => { - let (sender, receiver) = crate::channel_types::small_channel(); - self.termination_senders.lock().unwrap().push(sender); - Some(receiver) - } - NodeState::Terminated => None, - } - } - - /// Set the router to `Terminated` state and notify all tasks waiting for shutdown - pub(super) async fn terminate(&self) { - self.is_running - .store(false, core::sync::atomic::Ordering::Relaxed); - let previous = { - let mut guard = self.node_state.lock().unwrap(); - core::mem::replace(guard.deref_mut(), NodeState::Terminated) - }; - - match previous { - NodeState::Running | NodeState::Stopping => { - info!("No more workers left. Goodbye!"); - let senders = { - let mut guard = self.termination_senders.lock().unwrap(); - core::mem::take(guard.deref_mut()) - }; - for sender in senders { - let _ = sender.send(()).await; - } - } - NodeState::Terminated => {} - } - } - - pub(super) async fn wait_termination(&self) { - let mut receiver = { - let guard = self.node_state.lock().unwrap(); - match guard.deref() { - NodeState::Running | NodeState::Stopping => { - let (sender, receiver) = crate::channel_types::small_channel(); - self.termination_senders.lock().unwrap().push(sender); - receiver - } - NodeState::Terminated => { - return; - } - } - }; - receiver.recv().await; - } - - pub(super) fn running(&self) -> bool { - self.is_running.load(core::sync::atomic::Ordering::Relaxed) - } - - /// Check if this router is still `running`, meaning allows - /// spawning new workers and processors - pub(super) fn node_state(&self) -> NodeState { - self.node_state.lock().unwrap().clone() - } -} diff --git a/implementations/rust/ockam/ockam_node/src/router/worker.rs b/implementations/rust/ockam/ockam_node/src/router/worker.rs index 502b8531917..463054f6eae 100644 --- a/implementations/rust/ockam/ockam_node/src/router/worker.rs +++ b/implementations/rust/ockam/ockam_node/src/router/worker.rs @@ -1,92 +1,57 @@ -use crate::router::{AddressRecord, NodeState, Router, SenderPair, WorkerMeta}; -use crate::{error::NodeError, RouterReason}; +use crate::router::record::{AddressRecord, WorkerMeta}; +use crate::router::{Router, RouterState, SenderPair}; +use crate::WorkerShutdownPriority; use core::sync::atomic::AtomicUsize; use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{ - compat::{sync::Arc, vec::Vec}, - Address, AddressAndMetadata, Error, Result, -}; +use ockam_core::{compat::sync::Arc, Error, Mailboxes, Result}; impl Router { /// Start a new worker - pub fn start_worker( + pub fn add_worker( &self, - addrs: Vec
, + mailboxes: &Mailboxes, senders: SenderPair, detached: bool, - addresses_metadata: Vec, + shutdown_priority: WorkerShutdownPriority, metrics: Arc, ) -> Result<()> { - if !self.state.running() { - match self.state.node_state() { - NodeState::Stopping => Err(Error::new( - Origin::Node, - Kind::Shutdown, - "The node is shutting down", - ))?, - NodeState::Running => unreachable!(), - NodeState::Terminated => unreachable!(), - } - } else { - self.start_worker_impl(addrs, senders, detached, addresses_metadata, metrics) + if *self.state.read().unwrap() != RouterState::Running { + return Err(Error::new( + Origin::Node, + Kind::Shutdown, + "The node is shutting down", + ))?; } + + self.add_worker_impl(mailboxes, senders, detached, shutdown_priority, metrics) } - fn start_worker_impl( + fn add_worker_impl( &self, - addrs: Vec
, + mailboxes: &Mailboxes, senders: SenderPair, detached: bool, - addresses_metadata: Vec, + shutdown_priority: WorkerShutdownPriority, metrics: Arc, ) -> Result<()> { - let primary_addr = addrs - .first() - .ok_or_else(|| NodeError::RouterState(RouterReason::EmptyAddressSet).internal())?; - - debug!("Starting new worker '{}'", primary_addr); + debug!("Starting new worker '{}'", mailboxes.primary_address()); let SenderPair { msgs, ctrl } = senders; // Create an address record and insert it into the internal map let address_record = AddressRecord::new( - addrs.clone(), + mailboxes.primary_address().clone(), + mailboxes.additional_addresses().cloned().collect(), msgs, ctrl, - metrics, WorkerMeta { processor: false, detached, }, + shutdown_priority, + metrics, ); - self.map - .insert_address_record(primary_addr.clone(), address_record, addresses_metadata) - } - - /// Stop the worker - pub async fn stop_worker(&self, addr: &Address, detached: bool) -> Result<()> { - debug!("Stopping worker '{}'", addr); - - // Resolve any secondary address to the primary address - let primary_address = match self.map.get_primary_address(addr) { - Some(p) => p, - None => { - return Err(Error::new(Origin::Node, Kind::NotFound, "No such address") - .context("Address", addr)) - } - }; - - // If we are dropping a real worker, then we simply close the - // mailbox channel to trigger a graceful worker self-shutdown. - // The worker shutdown will call `free_address()`. - // - // For detached workers (i.e. Context's without a mailbox relay - // running) we simply free the address. - if detached { - self.map.free_address(&primary_address); - } else { - self.map.stop(&primary_address).await?; - } + self.map.insert_address_record(address_record, mailboxes)?; Ok(()) } diff --git a/implementations/rust/ockam/ockam_node/src/runtime.rs b/implementations/rust/ockam/ockam_node/src/runtime.rs deleted file mode 100644 index c354d06f214..00000000000 --- a/implementations/rust/ockam/ockam_node/src/runtime.rs +++ /dev/null @@ -1,16 +0,0 @@ -use once_cell::sync::Lazy; -use std::sync::Mutex; -use tokio::runtime::Runtime; - -pub(crate) static RUNTIME: Lazy>> = - Lazy::new(|| Mutex::new(Some(Runtime::new().unwrap()))); - -/// Return the Runtime singleton -/// This function can only be accessed once -pub fn take() -> Runtime { - RUNTIME - .lock() - .unwrap() - .take() - .expect("Runtime was consumed") -} diff --git a/implementations/rust/ockam/ockam_node/src/shutdown.rs b/implementations/rust/ockam/ockam_node/src/shutdown.rs deleted file mode 100644 index a75b1f8281b..00000000000 --- a/implementations/rust/ockam/ockam_node/src/shutdown.rs +++ /dev/null @@ -1,42 +0,0 @@ -/// Specify the type of node shutdown -/// -/// For most users `ShutdownType::Graceful()` is recommended. The -/// `Default` implementation uses a 1 second timeout. -#[derive(Debug, Copy, Clone)] -#[non_exhaustive] -pub enum ShutdownType { - /// Execute a graceful shutdown given a maximum timeout - /// - /// The following steps will be taken by the internal router - /// during graceful shutdown procedure: - /// - /// * Signal clusterless workers to stop - /// * Wait for shutdown ACK hooks from worker set - /// * Signal worker clusters in reverse-creation order to stop - /// * Wait for shutdown ACK hooks from each cluster before moving onto the - /// next - /// * All shutdown-signaled workers may process their entire mailbox, - /// while not allowing new messages to be queued - /// - /// Graceful shutdown procedure will be pre-maturely terminated - /// when reaching the timeout (failover into `Immediate` - /// strategy). **A given timeout of `0` will wait forever!** - Graceful(u8), - /// Immediately shutdown workers and run shutdown hooks - /// - /// This strategy can lead to data loss: - /// - /// * Unhandled mailbox messages will be dropped - /// * Shutdown hooks may not be able to send messages - /// - /// This strategy is not recommended for general use, but will be - /// selected as a failover, if the `Graceful` strategy reaches its - /// timeout limit. - Immediate, -} - -impl Default for ShutdownType { - fn default() -> Self { - Self::Graceful(1) - } -} diff --git a/implementations/rust/ockam/ockam_node/src/storage/database/sqlx_database.rs b/implementations/rust/ockam/ockam_node/src/storage/database/sqlx_database.rs index 72ca49f0f30..c1c9fca3adb 100644 --- a/implementations/rust/ockam/ockam_node/src/storage/database/sqlx_database.rs +++ b/implementations/rust/ockam/ockam_node/src/storage/database/sqlx_database.rs @@ -325,11 +325,17 @@ PRAGMA busy_timeout = 10000; install_default_drivers(); // SQLite in-memory DB get wiped if there is no connection to it. // The below setting tries to ensure there is always an open connection + let file_name = random_string(); + let options = AnyConnectOptions::from_str( + format!("sqlite:file:{file_name}?mode=memory&cache=shared").as_str(), + ) + .map_err(Self::map_sql_err)? + .log_statements(LevelFilter::Trace) + .log_slow_statements(LevelFilter::Trace, Duration::from_secs(1)); let pool_options = PoolOptions::new().idle_timeout(None).max_lifetime(None); - let file_name = random_string(); let pool = pool_options - .connect(format!("sqlite:file:{file_name}?mode=memory&cache=shared").as_str()) + .connect_with(options) .await .map_err(Self::map_sql_err)?; Ok(pool) diff --git a/implementations/rust/ockam/ockam_node/src/worker_builder.rs b/implementations/rust/ockam/ockam_node/src/worker_builder.rs index 3d980757551..d73dd335edb 100644 --- a/implementations/rust/ockam/ockam_node/src/worker_builder.rs +++ b/implementations/rust/ockam/ockam_node/src/worker_builder.rs @@ -1,9 +1,9 @@ -use crate::debugger; +use crate::{debugger, ContextMode, WorkerShutdownPriority}; use crate::{relay::WorkerRelay, Context}; -use alloc::string::String; -use ockam_core::compat::{sync::Arc, vec::Vec}; +use ockam_core::compat::string::String; +use ockam_core::compat::sync::Arc; use ockam_core::{ - Address, AddressAndMetadata, AddressMetadata, AllowAll, IncomingAccessControl, Mailboxes, + Address, AddressMetadata, AllowAll, IncomingAccessControl, Mailbox, Mailboxes, OutgoingAccessControl, Result, Worker, }; @@ -34,12 +34,42 @@ where { /// Worker with only one [`Address`] pub fn with_address(self, address: impl Into
) -> WorkerBuilderOneAddress { + self.with_address_and_metadata_impl(address, None) + } + + /// Worker with single terminal [`Address`] + pub fn with_terminal_address(self, address: impl Into
) -> WorkerBuilderOneAddress { + self.with_address_and_metadata( + address, + AddressMetadata { + is_terminal: true, + attributes: vec![], + }, + ) + } + + /// Worker with single terminal [`Address`] and metadata + pub fn with_address_and_metadata( + self, + address: impl Into
, + metadata: AddressMetadata, + ) -> WorkerBuilderOneAddress { + self.with_address_and_metadata_impl(address, Some(metadata)) + } + + /// Worker with single terminal [`Address`] and metadata + pub fn with_address_and_metadata_impl( + self, + address: impl Into
, + metadata: Option, + ) -> WorkerBuilderOneAddress { WorkerBuilderOneAddress { incoming_ac: Arc::new(AllowAll), outgoing_ac: Arc::new(AllowAll), worker: self.worker, address: address.into(), - metadata: None, + metadata, + shutdown_priority: Default::default(), } } @@ -47,8 +77,8 @@ where pub fn with_mailboxes(self, mailboxes: Mailboxes) -> WorkerBuilderMultipleAddresses { WorkerBuilderMultipleAddresses { mailboxes, + shutdown_priority: Default::default(), worker: self.worker, - metadata_list: vec![], } } } @@ -58,74 +88,23 @@ where W: Worker, { mailboxes: Mailboxes, + shutdown_priority: WorkerShutdownPriority, worker: W, - metadata_list: Vec, } impl WorkerBuilderMultipleAddresses where W: Worker, { - /// Mark the provided address as terminal - pub fn terminal(self, address: impl Into
) -> Self { - self.terminal_with_attributes(address.into(), vec![]) + /// Consume this builder and start a new Ockam [`Worker`] from the given context + pub fn start(self, context: &Context) -> Result<()> { + start(context, self.mailboxes, self.shutdown_priority, self.worker) } - /// Mark the provided address as terminal - pub fn terminal_with_attributes( - mut self, - address: impl Into
, - attributes: Vec<(String, String)>, - ) -> Self { - let address = address.into(); - let metadata = self.metadata_list.iter_mut().find(|m| m.address == address); - - if let Some(metadata) = metadata { - metadata.metadata.attributes = attributes; - metadata.metadata.is_terminal = true; - } else { - self.metadata_list.push(AddressAndMetadata { - address, - metadata: AddressMetadata { - is_terminal: true, - attributes, - }, - }); - } + pub fn with_shutdown_priority(mut self, shutdown_priority: WorkerShutdownPriority) -> Self { + self.shutdown_priority = shutdown_priority; self } - - /// Adds metadata attribute for the provided address - pub fn with_metadata_attribute( - mut self, - address: impl Into
, - key: impl Into, - value: impl Into, - ) -> Self { - let address = address.into(); - let metadata = self.metadata_list.iter_mut().find(|m| m.address == address); - - if let Some(metadata) = metadata { - metadata - .metadata - .attributes - .push((key.into(), value.into())); - } else { - self.metadata_list.push(AddressAndMetadata { - address, - metadata: AddressMetadata { - is_terminal: false, - attributes: vec![(key.into(), value.into())], - }, - }); - } - self - } - - /// Consume this builder and start a new Ockam [`Worker`] from the given context - pub async fn start(self, context: &Context) -> Result<()> { - start(context, self.mailboxes, self.worker, self.metadata_list).await - } } pub struct WorkerBuilderOneAddress @@ -136,67 +115,63 @@ where outgoing_ac: Arc, address: Address, worker: W, - metadata: Option, + metadata: Option, + shutdown_priority: WorkerShutdownPriority, } impl WorkerBuilderOneAddress where W: Worker, { - /// Mark the address as terminal - pub fn terminal(self) -> Self { - self.terminal_with_attributes(vec![]) - } - - /// Mark the address as terminal - pub fn terminal_with_attributes(mut self, attributes: Vec<(String, String)>) -> Self { - if let Some(metadata) = self.metadata.as_mut() { - metadata.metadata.is_terminal = true; - metadata.metadata.attributes = attributes; - } else { - self.metadata = Some(AddressAndMetadata { - address: self.address.clone(), - metadata: AddressMetadata { - is_terminal: true, - attributes, - }, - }); - } + /// Mark the provided address as terminal + pub fn terminal(mut self) -> Self { + self.metadata + .get_or_insert(AddressMetadata { + is_terminal: false, + attributes: vec![], + }) + .is_terminal = true; self } - /// Adds metadata attribute + /// Adds metadata attribute for the provided address pub fn with_metadata_attribute( mut self, key: impl Into, value: impl Into, ) -> Self { - if let Some(metadata) = self.metadata.as_mut() { - metadata - .metadata - .attributes - .push((key.into(), value.into())); - } else { - self.metadata = Some(AddressAndMetadata { - address: self.address.clone(), - metadata: AddressMetadata { - is_terminal: false, - attributes: vec![(key.into(), value.into())], - }, - }); - } + self.metadata + .get_or_insert(AddressMetadata { + is_terminal: false, + attributes: vec![], + }) + .attributes + .push((key.into(), value.into())); + + self + } + + pub fn with_shutdown_priority(mut self, shutdown_priority: WorkerShutdownPriority) -> Self { + self.shutdown_priority = shutdown_priority; self } /// Consume this builder and start a new Ockam [`Worker`] from the given context - pub async fn start(self, context: &Context) -> Result<()> { + pub fn start(self, context: &Context) -> Result<()> { start( context, - Mailboxes::main(self.address, self.incoming_ac, self.outgoing_ac), + Mailboxes::new( + Mailbox::new( + self.address, + self.metadata, + self.incoming_ac, + self.outgoing_ac, + ), + vec![], + ), + self.shutdown_priority, self.worker, - self.metadata.map(|m| vec![m]).unwrap_or_default(), ) - .await } } @@ -242,31 +217,35 @@ where } /// Consume this builder and start a new Ockam [`Worker`] from the given context -async fn start( +fn start( context: &Context, mailboxes: Mailboxes, + shutdown_priority: WorkerShutdownPriority, worker: W, - metadata: Vec, ) -> Result<()> where W: Worker, { debug!( "Initializing ockam worker '{}' with access control in:{:?} out:{:?}", - mailboxes.main_address(), - mailboxes.main_mailbox().incoming_access_control(), - mailboxes.main_mailbox().outgoing_access_control(), + mailboxes.primary_address(), + mailboxes.primary_mailbox().incoming_access_control(), + mailboxes.primary_mailbox().outgoing_access_control(), ); - let addresses = mailboxes.addresses(); - // Pass it to the context - let (ctx, sender, ctrl_rx) = context.copy_with_mailboxes(mailboxes); + let (ctx, sender, ctrl_rx) = context.new_with_mailboxes(mailboxes, ContextMode::Attached); debugger::log_inherit_context("WORKER", context, &ctx); - let router = context.router(); - router.start_worker(addresses, sender, false, metadata, context.mailbox_count())?; + let router = context.router()?; + router.add_worker( + ctx.mailboxes(), + sender, + false, + shutdown_priority, + context.mailbox_count(), + )?; // Then initialise the worker message relay WorkerRelay::init(context.runtime(), worker, ctx, ctrl_rx); diff --git a/implementations/rust/ockam/ockam_node/src/workers/echoer.rs b/implementations/rust/ockam/ockam_node/src/workers/echoer.rs index b8e3c0faa1c..13e2862d83a 100644 --- a/implementations/rust/ockam/ockam_node/src/workers/echoer.rs +++ b/implementations/rust/ockam/ockam_node/src/workers/echoer.rs @@ -15,7 +15,7 @@ impl Worker for Echoer { type Message = String; async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { - debug!("Address: {}, Received: {:?}", ctx.address(), msg); + debug!("Address: {}, Received: {:?}", ctx.primary_address(), msg); // Echo the message body back on its return_route. ctx.send(msg.return_route().clone(), msg.into_body()?).await diff --git a/implementations/rust/ockam/ockam_node/tests/router.rs b/implementations/rust/ockam/ockam_node/tests/metadata.rs similarity index 51% rename from implementations/rust/ockam/ockam_node/tests/router.rs rename to implementations/rust/ockam/ockam_node/tests/metadata.rs index 4ea18dba91a..3d24b2529fc 100644 --- a/implementations/rust/ockam/ockam_node/tests/router.rs +++ b/implementations/rust/ockam/ockam_node/tests/metadata.rs @@ -1,7 +1,8 @@ use ockam_core::{ - async_trait, route, Address, DenyAll, Mailbox, Mailboxes, Processor, Result, TransportType, + async_trait, route, AddressMetadata, DenyAll, Mailbox, Mailboxes, Processor, Result, }; use ockam_node::{Context, NullWorker, ProcessorBuilder, WorkerBuilder}; +use std::string::ToString; use std::sync::Arc; struct NullProcessor; @@ -20,69 +21,65 @@ impl Processor for NullProcessor { async fn find_terminal_for_processor(context: &mut Context) -> Result<()> { ProcessorBuilder::new(NullProcessor {}) .with_address("simple_processor") - .start(context) - .await?; + .start(context)?; assert!(context - .find_terminal_address(route!["simple_processor", "non-existing"]) - .await? + .find_terminal_address(route!["simple_processor", "non-existing"].iter())? .is_none()); ProcessorBuilder::new(NullProcessor {}) - .with_address("terminal_processor") - .terminal() - .start(context) - .await?; + .with_terminal_address("terminal_processor") + .start(context)?; assert_eq!( context - .find_terminal_address(route![ - "simple_worker", - "terminal_processor", - "non-existing" - ]) - .await? + .find_terminal_address( + route!["simple_worker", "terminal_processor", "non-existing"].iter() + )? .unwrap() - .address, - "terminal_processor".into() + .0, + &"terminal_processor".into() ); - context.stop().await + Ok(()) } #[ockam_macros::test] async fn find_terminal_for_processor_alias(context: &mut Context) -> Result<()> { ProcessorBuilder::new(NullProcessor {}) .with_mailboxes(Mailboxes::new( - Mailbox::new("main", Arc::new(DenyAll), Arc::new(DenyAll)), - vec![Mailbox::new("alias", Arc::new(DenyAll), Arc::new(DenyAll))], + Mailbox::new("main", None, Arc::new(DenyAll), Arc::new(DenyAll)), + vec![Mailbox::new( + "alias", + Some(AddressMetadata { + is_terminal: true, + attributes: vec![], + }), + Arc::new(DenyAll), + Arc::new(DenyAll), + )], )) - .terminal("alias") - .start(context) - .await?; + .start(context)?; assert!(context - .find_terminal_address(route!["main", "non-existing"]) - .await? + .find_terminal_address(route!["main", "non-existing"].iter())? .is_none()); assert_eq!( context - .find_terminal_address(route!["main", "alias", "other"]) - .await? + .find_terminal_address(route!["main", "alias", "other"].iter())? .unwrap() - .address, - "alias".into() + .0, + &"alias".into() ); - context.stop_processor("main").await?; + context.stop_address(&"main".into())?; ockam_node::compat::tokio::time::sleep(std::time::Duration::from_millis(10)).await; assert!(context - .find_terminal_address(route!["main", "alias", "other"]) - .await? + .find_terminal_address(route!["main", "alias", "other"].iter())? .is_none()); - context.stop().await + Ok(()) } #[ockam_macros::test] @@ -91,10 +88,9 @@ async fn provide_and_read_processor_address_metadata(context: &mut Context) -> R .with_address("processor_address") .with_metadata_attribute("TEST_KEY", "TEST_VALUE") .with_metadata_attribute("TEST_KEY_2", "TEST_VALUE_2") - .start(context) - .await?; + .start(context)?; - let meta = context.get_metadata("processor_address").unwrap(); + let meta = context.get_metadata(&"processor_address".into())?.unwrap(); assert!(!meta.is_terminal); @@ -106,98 +102,84 @@ async fn provide_and_read_processor_address_metadata(context: &mut Context) -> R ] ); - assert_eq!(context.get_metadata("non-existing-worker"), None); + assert_eq!(context.get_metadata(&"non-existing-worker".into())?, None); - context.stop_processor("processor_address").await?; + context.stop_address(&"processor_address".into())?; ockam_node::compat::tokio::time::sleep(std::time::Duration::from_millis(10)).await; - assert_eq!(context.get_metadata("processor_address"), None); + assert_eq!(context.get_metadata(&"processor_address".into())?, None); - context.stop().await + Ok(()) } #[ockam_macros::test] async fn find_terminal_for_worker(context: &mut Context) -> Result<()> { WorkerBuilder::new(NullWorker {}) .with_address("simple_worker") - .start(context) - .await?; + .start(context)?; assert!(context - .find_terminal_address(route!["simple_worker", "non-existing"]) - .await? + .find_terminal_address(route!["simple_worker", "non-existing"].iter())? .is_none()); WorkerBuilder::new(NullWorker {}) - .with_address("terminal_worker") - .terminal() - .start(context) - .await?; + .with_terminal_address("terminal_worker") + .start(context)?; assert_eq!( context - .find_terminal_address(route!["simple_worker", "terminal_worker", "non-existing"]) - .await? + .find_terminal_address( + route!["simple_worker", "terminal_worker", "non-existing"].iter() + )? .unwrap() - .address, - "terminal_worker".into() + .0, + &"terminal_worker".into() ); - let remote = Address::new_with_string(TransportType::new(1), "127.0.0.1"); - assert!(context - .find_terminal_address(route![ - "simple_worker", - remote, - "terminal_worker", - "non-existing" - ]) - .await - .is_err()); - - context.stop_worker("terminal_worker").await?; - ockam_node::compat::tokio::time::sleep(std::time::Duration::from_millis(10)).await; + context.stop_address(&"terminal_worker".into())?; assert_eq!( - context - .find_terminal_address(route!["terminal_worker"]) - .await?, + context.find_terminal_address(route!["terminal_worker"].iter())?, None ); - context.stop().await + Ok(()) } #[ockam_macros::test] async fn find_terminal_for_worker_alias(context: &mut Context) -> Result<()> { WorkerBuilder::new(NullWorker {}) .with_mailboxes(Mailboxes::new( - Mailbox::new("main", Arc::new(DenyAll), Arc::new(DenyAll)), - vec![Mailbox::new("alias", Arc::new(DenyAll), Arc::new(DenyAll))], + Mailbox::new("main", None, Arc::new(DenyAll), Arc::new(DenyAll)), + vec![Mailbox::new( + "alias", + Some(AddressMetadata { + is_terminal: true, + attributes: vec![], + }), + Arc::new(DenyAll), + Arc::new(DenyAll), + )], )) - .terminal("alias") - .start(context) - .await?; + .start(context)?; assert!(context - .find_terminal_address(route!["main", "non-existing"]) - .await? + .find_terminal_address(route!["main", "non-existing"].iter())? .is_none()); assert_eq!( context - .find_terminal_address(route!["main", "alias", "other"]) - .await? + .find_terminal_address(route!["main", "alias", "other"].iter())? .unwrap() - .address, - "alias".into() + .0, + &"alias".into() ); - context.stop_worker("main").await?; + context.stop_address(&"main".into())?; ockam_node::compat::tokio::time::sleep(std::time::Duration::from_millis(10)).await; assert!(context - .find_terminal_address(route!["main", "alias", "other"]) - .await? + .find_terminal_address(route!["main", "alias", "other"].iter())? .is_none()); - context.stop().await + Ok(()) } #[ockam_macros::test] @@ -206,10 +188,9 @@ async fn provide_and_read_address_metadata(context: &mut Context) -> Result<()> .with_address("worker_address") .with_metadata_attribute("TEST_KEY", "TEST_VALUE") .with_metadata_attribute("TEST_KEY_2", "TEST_VALUE_2") - .start(context) - .await?; + .start(context)?; - let meta = context.get_metadata("worker_address").unwrap(); + let meta = context.get_metadata(&"worker_address".into())?.unwrap(); assert!(!meta.is_terminal); @@ -221,28 +202,41 @@ async fn provide_and_read_address_metadata(context: &mut Context) -> Result<()> ] ); - assert_eq!(context.get_metadata("non-existing-worker"), None); + assert_eq!(context.get_metadata(&"non-existing-worker".into())?, None); - context.stop_worker("worker_address").await?; + context.stop_address(&"worker_address".into())?; ockam_node::compat::tokio::time::sleep(std::time::Duration::from_millis(10)).await; - assert_eq!(context.get_metadata("worker_address"), None); + assert_eq!(context.get_metadata(&"worker_address".into())?, None); - context.stop().await + Ok(()) } #[ockam_macros::test] async fn provide_and_read_address_metadata_worker_alias(context: &mut Context) -> Result<()> { WorkerBuilder::new(NullWorker {}) .with_mailboxes(Mailboxes::new( - Mailbox::new("main", Arc::new(DenyAll), Arc::new(DenyAll)), - vec![Mailbox::new("alias", Arc::new(DenyAll), Arc::new(DenyAll))], + Mailbox::new( + "main", + Some(AddressMetadata { + is_terminal: false, + attributes: vec![("TEST_KEY".to_string(), "TEST_VALUE".to_string())], + }), + Arc::new(DenyAll), + Arc::new(DenyAll), + ), + vec![Mailbox::new( + "alias", + Some(AddressMetadata { + is_terminal: false, + attributes: vec![("TEST_KEY_2".to_string(), "TEST_VALUE_2".to_string())], + }), + Arc::new(DenyAll), + Arc::new(DenyAll), + )], )) - .with_metadata_attribute("main", "TEST_KEY", "TEST_VALUE") - .with_metadata_attribute("alias", "TEST_KEY_2", "TEST_VALUE_2") - .start(context) - .await?; + .start(context)?; - let meta = context.get_metadata("alias").unwrap(); + let meta = context.get_metadata(&"alias".into())?.unwrap(); assert!(!meta.is_terminal); @@ -251,9 +245,9 @@ async fn provide_and_read_address_metadata_worker_alias(context: &mut Context) - vec![("TEST_KEY_2".to_string(), "TEST_VALUE_2".to_string())] ); - context.stop_worker("main").await?; + context.stop_address(&"main".into())?; ockam_node::compat::tokio::time::sleep(std::time::Duration::from_millis(10)).await; - assert_eq!(context.get_metadata("alias"), None); + assert_eq!(context.get_metadata(&"alias".into())?, None); - context.stop().await + Ok(()) } diff --git a/implementations/rust/ockam/ockam_node/tests/tests.rs b/implementations/rust/ockam/ockam_node/tests/tests.rs index 2bb8f7f98a9..46a04b319d7 100644 --- a/implementations/rust/ockam/ockam_node/tests/tests.rs +++ b/implementations/rust/ockam/ockam_node/tests/tests.rs @@ -6,19 +6,19 @@ use ockam_core::compat::{ sync::Arc, }; use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{async_trait, Address, AllowAll, Any, Decodable, DenyAll, Message, LOCAL}; +use ockam_core::{async_trait, Address, AllowAll, Any, Decodable, DenyAll, Message}; use ockam_core::{route, Processor, Result, Routed, Worker}; use ockam_node::compat::futures::FutureExt; use ockam_node::{Context, MessageReceiveOptions, NodeBuilder}; use serde::{Deserialize, Serialize}; -use std::sync::atomic::{AtomicI8, AtomicU32}; +use std::sync::atomic::AtomicI8; use std::time::{SystemTime, UNIX_EPOCH}; use tokio::time::sleep; #[allow(non_snake_case)] #[ockam_macros::test] async fn receive_timeout__1_sec__should_return_from_call(ctx: &mut Context) -> Result<()> { - let mut child_ctx = ctx.new_detached("random", AllowAll, AllowAll).await?; + let mut child_ctx = ctx.new_detached("random", AllowAll, AllowAll)?; let time = SystemTime::now(); let start = time.duration_since(UNIX_EPOCH).unwrap(); @@ -43,8 +43,8 @@ fn start_and_shutdown_node__many_iterations__should_not_fail() { executor .execute(async move { let res = std::panic::AssertUnwindSafe(async { - let child_ctx1 = ctx.new_detached("child1", AllowAll, AllowAll).await?; - let mut child_ctx2 = ctx.new_detached("child2", AllowAll, AllowAll).await?; + let child_ctx1 = ctx.new_detached("child1", AllowAll, AllowAll)?; + let mut child_ctx2 = ctx.new_detached("child2", AllowAll, AllowAll)?; child_ctx1 .send(route!["child2"], "Hello".to_string()) .await?; @@ -57,7 +57,7 @@ fn start_and_shutdown_node__many_iterations__should_not_fail() { .catch_unwind() .await; - ctx.stop().await?; + ctx.shutdown_node().await?; res.unwrap() }) @@ -65,6 +65,7 @@ fn start_and_shutdown_node__many_iterations__should_not_fail() { .unwrap() } } + struct SimpleWorker { initialize_was_called: Arc, shutdown_was_called: Arc, @@ -99,6 +100,30 @@ impl Worker for SimpleWorker { } } +#[allow(non_snake_case)] +#[ockam_macros::test] +async fn simple_worker__run_node_lifecycle__should_not_fail(ctx: &mut Context) -> Result<()> { + let initialize_was_called = Arc::new(AtomicBool::new(false)); + let shutdown_was_called = Arc::new(AtomicBool::new(false)); + + let initialize_was_called_clone = initialize_was_called.clone(); + let shutdown_was_called_clone = shutdown_was_called.clone(); + + let worker = SimpleWorker { + initialize_was_called: initialize_was_called_clone, + shutdown_was_called: shutdown_was_called_clone, + }; + + ctx.start_worker("simple_worker", worker)?; + + let msg: String = ctx + .send_and_receive(route!["simple_worker"], "Hello".to_string()) + .await?; + assert_eq!(msg, "Hello"); + + Ok(()) +} + #[allow(non_snake_case)] #[ockam_macros::test] async fn simple_worker__run_node_lifecycle__worker_lifecycle_should_be_full( @@ -115,20 +140,20 @@ async fn simple_worker__run_node_lifecycle__worker_lifecycle_should_be_full( shutdown_was_called: shutdown_was_called_clone, }; - ctx.start_worker("simple_worker", worker).await?; + ctx.start_worker("simple_worker", worker)?; let msg: String = ctx .send_and_receive(route!["simple_worker"], "Hello".to_string()) .await?; assert_eq!(msg, "Hello"); - ctx.stop().await?; + ctx.shutdown_node().await?; // Wait till tokio Runtime is shut down - // std::thread::sleep(Duration::new(1, 0)); sleep(Duration::new(1, 0)).await; assert!(initialize_was_called.load(Ordering::Relaxed)); assert!(shutdown_was_called.load(Ordering::Relaxed)); + Ok(()) } @@ -167,12 +192,12 @@ async fn worker_initialize_fail_should_shutdown(ctx: &mut Context) -> Result<()> let worker = FailingWorkerProcessor { shutdown_was_called: shutdown_was_called.clone(), }; - let res = ctx.start_worker(address.clone(), worker).await; + let res = ctx.start_worker(address.clone(), worker); assert!(res.is_ok()); sleep(Duration::new(1, 0)).await; assert!(shutdown_was_called.load(Ordering::Relaxed)); - assert!(!ctx.list_workers().contains(&address)); + assert!(!ctx.list_workers()?.contains(&address)); Ok(()) } @@ -203,11 +228,11 @@ async fn processor_initialize_fail_should_shutdown(ctx: &mut Context) -> Result< let processor = FailingWorkerProcessor { shutdown_was_called: shutdown_was_called.clone(), }; - let res = ctx.start_processor(address.clone(), processor).await; + let res = ctx.start_processor(address.clone(), processor); assert!(res.is_ok()); sleep(Duration::new(1, 0)).await; assert!(shutdown_was_called.load(Ordering::Relaxed)); - assert!(!ctx.list_workers().contains(&address)); + assert!(!ctx.list_workers()?.contains(&address)); Ok(()) } @@ -226,11 +251,9 @@ impl Processor for DummyProcessor { #[ockam_macros::test] async fn starting_processor_with_dup_address_should_fail(ctx: &mut Context) -> Result<()> { - ctx.start_processor("dummy_processor", DummyProcessor) - .await?; + ctx.start_processor("dummy_processor", DummyProcessor)?; assert!(ctx .start_processor("dummy_processor", DummyProcessor) - .await .is_err()); Ok(()) } @@ -286,7 +309,7 @@ async fn counting_processor__run_node_lifecycle__processor_lifecycle_should_be_f run_called_count: run_called_count_clone, }; - ctx.start_processor("counting_processor", processor).await?; + ctx.start_processor("counting_processor", processor)?; sleep(Duration::from_secs(1)).await; assert!(initialize_was_called.load(Ordering::Relaxed)); @@ -333,10 +356,10 @@ async fn waiting_processor__shutdown__should_be_interrupted(ctx: &mut Context) - shutdown_was_called: shutdown_was_called.clone(), }; - ctx.start_processor("waiting_processor", processor).await?; + ctx.start_processor("waiting_processor", processor)?; sleep(Duration::from_secs(1)).await; - ctx.stop_processor("waiting_processor").await?; + ctx.stop_address(&"waiting_processor".into())?; sleep(Duration::from_secs(1)).await; assert!(initialize_was_called.load(Ordering::Relaxed)); @@ -401,15 +424,16 @@ async fn waiting_processor__messaging__should_work(ctx: &mut Context) -> Result< shutdown_was_called: shutdown_was_called_clone, }; - ctx.start_processor_with_access_control("messaging_processor", processor, AllowAll, AllowAll) - .await?; - sleep(Duration::new(1, 0)).await; + ctx.start_processor_with_access_control("messaging_processor", processor, AllowAll, AllowAll)?; + sleep(Duration::from_millis(250)).await; let msg: String = ctx .send_and_receive(route!["messaging_processor"], "Keep working".to_string()) .await?; assert_eq!("OK", msg); + sleep(Duration::from_millis(250)).await; + assert!(initialize_was_called.load(Ordering::Relaxed)); assert!(!shutdown_was_called.load(Ordering::Relaxed)); @@ -418,6 +442,8 @@ async fn waiting_processor__messaging__should_work(ctx: &mut Context) -> Result< .await?; assert_eq!("I go home", msg); + sleep(Duration::from_millis(250)).await; + assert!(initialize_was_called.load(Ordering::Relaxed)); assert!(shutdown_was_called.load(Ordering::Relaxed)); @@ -443,78 +469,13 @@ impl Worker for BadWorker { #[ockam_macros::test] async fn abort_blocked_shutdown(ctx: &mut Context) -> Result<()> { // Create an executor - ctx.start_worker_with_access_control("bad", BadWorker, DenyAll, DenyAll) - .await?; + ctx.start_worker_with_access_control("bad", BadWorker, DenyAll, DenyAll)?; - ockam_node::tokio::time::timeout(Duration::from_secs(2), ctx.stop()) + ockam_node::tokio::time::timeout(Duration::from_secs(2), ctx.shutdown_node()) .await .unwrap() } -struct StopFromHandleMessageWorker { - counter_a: Arc, - counter_b: Arc, -} - -#[async_trait] -impl Worker for StopFromHandleMessageWorker { - type Message = String; - type Context = Context; - async fn handle_message(&mut self, ctx: &mut Context, _msg: Routed) -> Result<()> { - self.counter_a.fetch_add(1, Ordering::Relaxed); - ctx.stop_worker(ctx.address()).await?; - self.counter_b.fetch_add(1, Ordering::Relaxed); - Ok(()) - } -} - -/// Test that a Worker can complete execution of its handle_message() -/// even if it calls Context::stop_worker() from within handle_message(). -/// See https://github.com/build-trust/ockam/issues/2283 -/// See https://github.com/build-trust/ockam/issues/2280 -#[ockam_macros::test] -async fn worker_calls_stopworker_from_handlemessage(ctx: &mut Context) -> Result<()> { - let counter_a = Arc::new(AtomicU32::new(0)); - let counter_b = Arc::new(AtomicU32::new(0)); - let counter_a_clone = counter_a.clone(); - let counter_b_clone = counter_b.clone(); - - let child_ctx = ctx.new_detached("child", AllowAll, AllowAll).await?; - - const RUNS: u32 = 1000; - const WORKERS: u32 = 10; - for _ in 0..RUNS { - let mut addrs = Vec::new(); - for _ in 0..WORKERS { - let worker = StopFromHandleMessageWorker { - counter_a: counter_a_clone.clone(), - counter_b: counter_b_clone.clone(), - }; - let addr = Address::random(LOCAL); - ctx.start_worker(addr.clone(), worker).await.unwrap(); - addrs.push(addr); - } - - let mut join_handles = Vec::new(); - for addr in addrs { - join_handles.push(child_ctx.send(route![addr], String::from("Testing. 1. 2. 3."))); - } - - for h in join_handles { - h.await.unwrap(); - } - } - // Wait till tokio Runtime is shut down - std::thread::sleep(Duration::new(1, 0)); - - // Assert all handle_message() entry and exit counts match - assert_eq!( - counter_a.load(Ordering::Relaxed), - counter_b.load(Ordering::Relaxed) - ); - Ok(()) -} - struct SendReceiveWorker; #[async_trait] @@ -533,7 +494,7 @@ impl Worker for SendReceiveWorker { } } - ctx.stop().await + ctx.shutdown_node().await } } @@ -551,8 +512,7 @@ enum SendReceiveResponse { /// See https://github.com/build-trust/ockam/issues/2628. #[ockam_macros::test] async fn use_context_send_and_receive(ctx: &mut Context) -> Result<()> { - ctx.start_worker("SendReceiveWorker", SendReceiveWorker) - .await?; + ctx.start_worker("SendReceiveWorker", SendReceiveWorker)?; let msg_tx = SendReceiveRequest::Connect(); let msg_rx = ctx.send_and_receive("SendReceiveWorker", msg_tx).await?; @@ -589,11 +549,9 @@ impl Worker for DummyWorker { #[ockam_macros::test] async fn starting_worker_with_dup_address_should_fail(ctx: &mut Context) -> Result<()> { - ctx.start_worker_with_access_control("dummy_worker", DummyWorker, DenyAll, DenyAll) - .await?; + ctx.start_worker_with_access_control("dummy_worker", DummyWorker, DenyAll, DenyAll)?; assert!(ctx .start_worker_with_access_control("dummy_worker", DummyWorker, DenyAll, DenyAll) - .await .is_err()); Ok(()) } @@ -614,7 +572,7 @@ impl Worker for CountingErrorWorker { ) -> Result<()> { let _ = self.counter.fetch_add(1, Ordering::Relaxed); - Err(ockam_core::Error::new(Origin::Core, Kind::Misuse, "")) + Err(ockam_core::Error::new(Origin::Core, Kind::Misuse, "test")) } } @@ -629,8 +587,7 @@ async fn message_handle__error_during_handling__keep_worker_running( CountingErrorWorker { counter: counter.clone(), }, - ) - .await?; + )?; ctx.send("counter", "test".to_string()).await?; ctx.sleep(Duration::from_millis(100)).await; diff --git a/implementations/rust/ockam/ockam_transport_ble/examples/04-routing-over-ble-transport-initiator.rs b/implementations/rust/ockam/ockam_transport_ble/examples/04-routing-over-ble-transport-initiator.rs index 24b96036670..42bc3eb8d87 100644 --- a/implementations/rust/ockam/ockam_transport_ble/examples/04-routing-over-ble-transport-initiator.rs +++ b/implementations/rust/ockam/ockam_transport_ble/examples/04-routing-over-ble-transport-initiator.rs @@ -20,7 +20,7 @@ async fn async_main(mut ctx: Context) -> Result<()> { let ble_client = BleClient::with_adapter(ble_adapter); // Initialize the BLE Transport. - let ble = BleTransport::create(&ctx).await?; + let ble = BleTransport::create(&ctx)?; // Try to connect to BleServer ble.connect(ble_client, "ockam_ble_1".to_string()).await?; @@ -34,5 +34,5 @@ async fn async_main(mut ctx: Context) -> Result<()> { println!("[main] App Received: {}", reply.into_body()?); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - ctx.stop().await + ctx.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam_transport_ble/examples/05-secure-channel-over-ble-transport-initiator.rs b/implementations/rust/ockam/ockam_transport_ble/examples/05-secure-channel-over-ble-transport-initiator.rs index 632ec22fa7b..8ad75141181 100644 --- a/implementations/rust/ockam/ockam_transport_ble/examples/05-secure-channel-over-ble-transport-initiator.rs +++ b/implementations/rust/ockam/ockam_transport_ble/examples/05-secure-channel-over-ble-transport-initiator.rs @@ -21,7 +21,7 @@ async fn async_main(mut ctx: Context) -> Result<()> { let ble_client = BleClient::with_adapter(ble_adapter); // Initialize the BLE Transport. - let ble = BleTransport::create(&ctx).await?; + let ble = BleTransport::create(&ctx)?; // Create an Entity to represent Alice. let secure_channels = secure_channels().await?; @@ -49,5 +49,5 @@ async fn async_main(mut ctx: Context) -> Result<()> { println!("[main] App Received: {}", reply.into_body()?); // should print "Hello Ockam!" // Stop all workers, stop the node, cleanup and return. - ctx.stop().await + ctx.shutdown_node().await } diff --git a/implementations/rust/ockam/ockam_transport_ble/src/lib.rs b/implementations/rust/ockam/ockam_transport_ble/src/lib.rs index 651d66335ad..b4dd95dded3 100644 --- a/implementations/rust/ockam/ockam_transport_ble/src/lib.rs +++ b/implementations/rust/ockam/ockam_transport_ble/src/lib.rs @@ -39,5 +39,3 @@ pub use types::*; /// BLE address type constant pub const BLE: TransportType = TransportType::new(4); - -pub(crate) const CLUSTER_NAME: &str = "_internals.transport.ble"; diff --git a/implementations/rust/ockam/ockam_transport_ble/src/router/handle.rs b/implementations/rust/ockam/ockam_transport_ble/src/router/handle.rs index d6fc8e02597..e690f51f71f 100644 --- a/implementations/rust/ockam/ockam_transport_ble/src/router/handle.rs +++ b/implementations/rust/ockam/ockam_transport_ble/src/router/handle.rs @@ -5,38 +5,21 @@ use crate::{ }; use crate::router::BleRouterMessage; -use ockam_core::{ - async_trait, - compat::{boxed::Box, string::String, vec::Vec}, - AllowAll, -}; -use ockam_core::{Address, AsyncTryClone, Result}; +use ockam_core::compat::{string::String, vec::Vec}; +use ockam_core::{Address, Result, TryClone}; use ockam_node::Context; use ockam_transport_core::TransportError; /// A handle to connect to a BleRouter /// /// Dropping this handle is harmless. +#[derive(TryClone)] +#[try_clone(crate = "ockam_core")] pub(crate) struct BleRouterHandle { ctx: Context, api_addr: Address, } -#[async_trait] -impl AsyncTryClone for BleRouterHandle { - async fn async_try_clone(&self) -> Result { - let child_ctx = self - .ctx - .new_detached( - Address::random_tagged("BleRouterHandle.async_try_clone.detached"), - AllowAll, - AllowAll, - ) - .await?; - Ok(Self::new(child_ctx, self.api_addr.clone())) - } -} - impl BleRouterHandle { pub(crate) fn new(ctx: Context, api_addr: Address) -> Self { BleRouterHandle { ctx, api_addr } @@ -72,13 +55,7 @@ impl BleRouterHandle { addr: S, ) -> Result<()> { let ble_addr = addr.into(); - BleListenProcessor::start( - ble_server, - &self.ctx, - self.async_try_clone().await?, - ble_addr, - ) - .await + BleListenProcessor::start(ble_server, &self.ctx, self.try_clone()?, ble_addr).await } // TODO: Remove in favor of `ockam_node::compat::asynchronous::resolve_peer` @@ -113,7 +90,7 @@ impl BleRouterHandle { ble_client.connect().await?; let stream = crate::driver::AsyncStream::with_ble_device(ble_client); - let pair = BleSendWorker::start_pair(&self.ctx, stream, peer_addr, servicenames).await?; + let pair = BleSendWorker::start_pair(&self.ctx, stream, peer_addr, servicenames)?; self.register(&pair).await?; diff --git a/implementations/rust/ockam/ockam_transport_ble/src/router/mod.rs b/implementations/rust/ockam/ockam_transport_ble/src/router/mod.rs index 4a90bac6cf9..d3f8dbeec72 100644 --- a/implementations/rust/ockam/ockam_transport_ble/src/router/mod.rs +++ b/implementations/rust/ockam/ockam_transport_ble/src/router/mod.rs @@ -40,14 +40,12 @@ pub struct BleRouter { } impl BleRouter { - async fn create_self_handle(&self, ctx: &Context) -> Result { - let handle_ctx = ctx - .new_detached( - Address::random_tagged("BleRouterHandle.async_try_clone.detached"), - AllowAll, - AllowAll, - ) - .await?; + fn create_self_handle(&self, ctx: &Context) -> Result { + let handle_ctx = ctx.new_detached( + Address::random_tagged("BleRouterHandle.try_clone.detached"), + AllowAll, + AllowAll, + )?; let handle = BleRouterHandle::new(handle_ctx, self.api_addr.clone()); Ok(handle) } @@ -86,7 +84,7 @@ impl BleRouter { let onward = msg.next_on_onward_route()?; // Look up the connection worker responsible - let next = match self.map.get(&onward) { + let next = match self.map.get(onward) { Some(addr) => addr.clone(), None => { error!("unknown route: {:?}", onward); @@ -95,7 +93,7 @@ impl BleRouter { }; // Modify the transport message route - let msg = msg.replace_front_onward_route(&next)?; + let msg = msg.replace_front_onward_route(next.clone())?; // Send the transport message to the connection worker ctx.send(next.clone(), msg).await?; @@ -109,11 +107,6 @@ impl Worker for BleRouter { type Context = Context; type Message = Any; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await?; - Ok(()) - } - async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { let msg_addr = msg.msg_addr(); @@ -142,18 +135,16 @@ impl BleRouter { /// /// To also handle incoming connections, use /// [`BleRouter::bind`](BleRouter::bind) - pub(crate) async fn register(ctx: &Context) -> Result { + pub(crate) fn register(ctx: &Context) -> Result { let main_addr = Address::random_tagged("BleRouter.main_addr"); let api_addr = Address::random_tagged("BleRouter.api_addr"); debug!("Registering new BleRouter with address {}", &main_addr); - let child_ctx = ctx - .new_detached( - Address::random_tagged("BleRouter.detached_child"), - AllowAll, - AllowAll, - ) - .await?; + let child_ctx = ctx.new_detached( + Address::random_tagged("BleRouter.detached_child"), + AllowAll, + AllowAll, + )?; let router = Self { _ctx: child_ctx, main_addr: main_addr.clone(), @@ -161,23 +152,28 @@ impl BleRouter { map: BTreeMap::new(), }; - let handle = router.create_self_handle(ctx).await?; + let handle = router.create_self_handle(ctx)?; trace!("Start Ble router for address = {:?}", main_addr.clone()); // TODO: @ac let mailboxes = Mailboxes::new( - Mailbox::new(main_addr.clone(), Arc::new(AllowAll), Arc::new(AllowAll)), + Mailbox::new( + main_addr.clone(), + None, + Arc::new(AllowAll), + Arc::new(AllowAll), + ), vec![Mailbox::new( api_addr, + None, Arc::new(AllowAll), Arc::new(AllowAll), )], ); WorkerBuilder::new(router) .with_mailboxes(mailboxes) - .start(ctx) - .await?; + .start(ctx)?; trace!("Registering Ble router for type = {}", crate::BLE); ctx.register(crate::BLE, main_addr)?; diff --git a/implementations/rust/ockam/ockam_transport_ble/src/transport.rs b/implementations/rust/ockam/ockam_transport_ble/src/transport.rs index 4c92a41e4de..9a25ad0db8c 100644 --- a/implementations/rust/ockam/ockam_transport_ble/src/transport.rs +++ b/implementations/rust/ockam/ockam_transport_ble/src/transport.rs @@ -1,8 +1,7 @@ use core::str::FromStr; use core::sync::atomic::{AtomicBool, Ordering}; -use ockam_core::compat::boxed::Box; -use ockam_core::{async_trait, AsyncTryClone, Result}; +use ockam_core::Result; use ockam_node::Context; use crate::driver::{BleClient, BleServer}; @@ -34,7 +33,7 @@ use crate::BleAddr; /// let ble_client = BleClient::with_adapter(ble_adapter); /// /// // Initialize the BLE Transport. -/// let ble = BleTransport::create(&ctx).await?; +/// let ble = BleTransport::create(&ctx)?; /// /// // Try to connect to BleServer /// ble.connect(ble_client, "ockam_ble_1".to_string()).await?; @@ -44,24 +43,15 @@ pub struct BleTransport { router_handle: BleRouterHandle, } -#[async_trait] -impl AsyncTryClone for BleTransport { - async fn async_try_clone(&self) -> Result { - Ok(Self { - router_handle: self.router_handle.async_try_clone().await?, - }) - } -} - impl BleTransport { /// Create a new BLE transport and router for the current node - pub async fn create(ctx: &Context) -> Result { + pub fn create(ctx: &Context) -> Result { static CREATED: AtomicBool = AtomicBool::new(false); if CREATED.swap(true, Ordering::SeqCst) { panic!("You may only create one BleTransport per node."); } - let router_handle = BleRouter::register(ctx).await?; + let router_handle = BleRouter::register(ctx)?; Ok(Self { router_handle }) } diff --git a/implementations/rust/ockam/ockam_transport_ble/src/workers/listener.rs b/implementations/rust/ockam/ockam_transport_ble/src/workers/listener.rs index 697c471f774..e0cc225fc11 100644 --- a/implementations/rust/ockam/ockam_transport_ble/src/workers/listener.rs +++ b/implementations/rust/ockam/ockam_transport_ble/src/workers/listener.rs @@ -41,8 +41,7 @@ where ctx.start_processor_with_access_control( waddr, processor, AllowAll, // FIXME: @ac AllowAll, // FIXME: @ac - ) - .await?; + )?; Ok(()) } @@ -55,10 +54,6 @@ where { type Context = Context; - async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await - } - async fn process(&mut self, ctx: &mut Self::Context) -> Result { if self.inner.is_none() { return Ok(true); @@ -82,8 +77,7 @@ where // TODO resolve connecting BleClient's addresses crate::parse_ble_addr("ble_client_addr").unwrap(), vec![], - ) - .await?; + )?; // Register the connection with the local BleRouter trace!("Registering WorkerPair tx stream with BleRouterHandle"); diff --git a/implementations/rust/ockam/ockam_transport_ble/src/workers/receiver.rs b/implementations/rust/ockam/ockam_transport_ble/src/workers/receiver.rs index 8c8fe2bc998..5ebb827694e 100644 --- a/implementations/rust/ockam/ockam_transport_ble/src/workers/receiver.rs +++ b/implementations/rust/ockam/ockam_transport_ble/src/workers/receiver.rs @@ -38,10 +38,6 @@ where { type Context = Context; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await - } - async fn process(&mut self, ctx: &mut Context) -> Result { let mut buffer = [0_u8; crate::driver::MAX_OCKAM_MESSAGE_LENGTH]; @@ -101,7 +97,7 @@ where // Insert the peer address into the return route so that // reply routing can be properly resolved - msg = msg.push_front_return_route(&self.peer_addr); + msg = msg.push_front_return_route(self.peer_addr.clone()); // Some verbose logging we may want to remove debug!("Message onward route: {}", msg.onward_route()); diff --git a/implementations/rust/ockam/ockam_transport_ble/src/workers/sender.rs b/implementations/rust/ockam/ockam_transport_ble/src/workers/sender.rs index fdc1a94a855..e0c434f1061 100644 --- a/implementations/rust/ockam/ockam_transport_ble/src/workers/sender.rs +++ b/implementations/rust/ockam/ockam_transport_ble/src/workers/sender.rs @@ -52,7 +52,7 @@ where } } - pub(crate) async fn start_pair( + pub(crate) fn start_pair( ctx: &Context, stream: AsyncStream, peer: BleAddr, @@ -64,7 +64,7 @@ where let sender = BleSendWorker::new(stream, peer.clone()); debug!("start send worker({:?})", tx_addr.clone()); - ctx.start_worker(tx_addr.clone(), sender).await?; + ctx.start_worker(tx_addr.clone(), sender)?; Ok(WorkerPair { servicenames, @@ -83,8 +83,6 @@ where type Message = TransportMessage; async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await?; - debug!("initialize for peer: {:?}", self.peer); if let Some(rx_stream) = self.rx_stream.take() { @@ -96,8 +94,7 @@ where receiver, AllowAll, // FIXME: @ac AllowAll, // FIXME: @ac - ) - .await?; + )?; debug!("started receiver"); } else { error!("TransportError::GenericIo"); @@ -135,7 +132,7 @@ where Ok(_) => (), Err(e) => { error!("Failed to send fragment to peer {}: {:?}", self.peer, e); - ctx.stop_worker(ctx.address()).await?; + ctx.stop_address(ctx.primary_address())?; } } @@ -147,7 +144,7 @@ where Ok(_) => (), Err(e) => { error!("Failed to send fragment to peer {}: {:?}", self.peer, e); - ctx.stop_worker(ctx.address()).await?; + ctx.stop_address(ctx.primary_address())?; } } diff --git a/implementations/rust/ockam/ockam_transport_core/src/transport.rs b/implementations/rust/ockam/ockam_transport_core/src/transport.rs index 51556c07225..31c61cb151d 100644 --- a/implementations/rust/ockam/ockam_transport_core/src/transport.rs +++ b/implementations/rust/ockam/ockam_transport_core/src/transport.rs @@ -16,10 +16,10 @@ pub trait Transport: Send + Sync + 'static { /// Instantiate transport workers for in order to communicate with a remote address /// and return the local address of the transport worker - async fn resolve_address(&self, address: Address) -> Result
; + async fn resolve_address(&self, address: &Address) -> Result
; /// Stop all workers and free all resources associated with the connection - async fn disconnect(&self, address: Address) -> Result<()>; + fn disconnect(&self, address: &Address) -> Result<()>; } /// Helper that creates a length-prefixed buffer containing the given diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/lib.rs b/implementations/rust/ockam/ockam_transport_tcp/src/lib.rs index 43dffb09877..e83c06d6a81 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/lib.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/lib.rs @@ -41,8 +41,6 @@ pub use transport::*; /// eBPF backed TCP portals that works on TCP level rather than on top of TCP pub mod privileged_portal; -pub(crate) const CLUSTER_NAME: &str = "_internals.transport.tcp"; - /// Transport type for TCP addresses pub const TCP: ockam_core::TransportType = ockam_core::TransportType::new(1); diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/options.rs b/implementations/rust/ockam/ockam_transport_tcp/src/options.rs index ff17ffd8d9d..a500f816401 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/options.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/options.rs @@ -36,14 +36,14 @@ impl TcpConnectionOptions { impl TcpConnectionOptions { pub(crate) fn setup_flow_control(&self, flow_controls: &FlowControls, addresses: &Addresses) { flow_controls.add_producer( - addresses.receiver_address().clone(), + addresses.receiver_address(), &self.flow_control_id, None, vec![addresses.sender_address().clone()], ); for id in &self.consumer { - flow_controls.add_consumer(addresses.sender_address().clone(), id); + flow_controls.add_consumer(addresses.sender_address(), id); } } @@ -88,7 +88,7 @@ impl TcpListenerOptions { flow_controls: &FlowControls, address: &Address, ) { - flow_controls.add_spawner(address.clone(), &self.flow_control_id); + flow_controls.add_spawner(address, &self.flow_control_id); } pub(crate) fn setup_flow_control_for_connection( @@ -99,7 +99,7 @@ impl TcpListenerOptions { let flow_control_id = FlowControls::generate_flow_control_id(); flow_controls.add_producer( - addresses.receiver_address().clone(), + addresses.receiver_address(), &flow_control_id, Some(&self.flow_control_id), vec![addresses.sender_address().clone()], diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/portal/inlet_listener.rs b/implementations/rust/ockam/ockam_transport_tcp/src/portal/inlet_listener.rs index 07e2941b9e6..cd6c1e38859 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/portal/inlet_listener.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/portal/inlet_listener.rs @@ -4,11 +4,10 @@ use crate::portal::{InletSharedState, ReadHalfMaybeTls, WriteHalfMaybeTls}; use crate::{portal::TcpPortalWorker, TcpInlet, TcpInletOptions, TcpRegistry}; use log::warn; use ockam_core::compat::net::SocketAddr; -use ockam_core::compat::sync::Arc; +use ockam_core::compat::sync::{Arc, RwLock as SyncRwLock}; use ockam_core::errcode::{Kind, Origin}; use ockam_core::{async_trait, compat::boxed::Box, Result}; use ockam_core::{Address, Processor, Route}; -use ockam_node::compat::asynchronous::RwLock; use ockam_node::Context; use ockam_transport_core::{HostnamePort, TransportError}; use rustls::pki_types::CertificateDer; @@ -27,7 +26,7 @@ use tracing::{debug, error, instrument}; pub(crate) struct TcpInletListenProcessor { registry: TcpRegistry, inner: TcpListener, - inlet_shared_state: Arc>, + inlet_shared_state: Arc>, options: TcpInletOptions, } @@ -35,7 +34,7 @@ impl TcpInletListenProcessor { pub fn new( registry: TcpRegistry, inner: TcpListener, - inlet_shared_state: Arc>, + inlet_shared_state: Arc>, options: TcpInletOptions, ) -> Self { Self { @@ -67,12 +66,11 @@ impl TcpInletListenProcessor { }; let socket_addr = inner.local_addr().map_err(TransportError::from)?; let inlet_shared_state = - InletSharedState::create(ctx, outlet_listener_route, options.is_paused).await?; - let inlet_shared_state = Arc::new(RwLock::new(inlet_shared_state)); + InletSharedState::create(ctx, outlet_listener_route, options.is_paused)?; + let inlet_shared_state = Arc::new(SyncRwLock::new(inlet_shared_state)); let processor = Self::new(registry, inner, inlet_shared_state.clone(), options); - ctx.start_processor(processor_address.clone(), processor) - .await?; + ctx.start_processor(processor_address.clone(), processor)?; Ok(TcpInlet::new_regular( socket_addr, @@ -162,7 +160,8 @@ impl Processor for TcpInletListenProcessor { #[instrument(skip_all, name = "TcpInletListenProcessor::initialize")] async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.registry.add_inlet_listener_processor(&ctx.address()); + self.registry + .add_inlet_listener_processor(ctx.primary_address()); Ok(()) } @@ -170,7 +169,7 @@ impl Processor for TcpInletListenProcessor { #[instrument(skip_all, name = "TcpInletListenProcessor::shutdown")] async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { self.registry - .remove_inlet_listener_processor(&ctx.address()); + .remove_inlet_listener_processor(ctx.primary_address()); Ok(()) } @@ -181,7 +180,7 @@ impl Processor for TcpInletListenProcessor { let addresses = Addresses::generate(PortalType::Inlet); - let inlet_shared_state = self.inlet_shared_state.read().await.clone(); + let inlet_shared_state = self.inlet_shared_state.read().unwrap().clone(); if inlet_shared_state.is_paused() { // Just drop the stream @@ -226,8 +225,7 @@ impl Processor for TcpInletListenProcessor { addresses, self.options.incoming_access_control.clone(), self.options.outgoing_access_control.clone(), - ) - .await?; + )?; Ok(true) } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/portal/inlet_shared_state.rs b/implementations/rust/ockam/ockam_transport_tcp/src/portal/inlet_shared_state.rs index 4322b3458b8..799533de155 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/portal/inlet_shared_state.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/portal/inlet_shared_state.rs @@ -19,10 +19,10 @@ pub struct InletSharedState { } impl InletSharedState { - pub async fn create(ctx: &Context, route: Route, is_paused: bool) -> Result { + pub fn create(ctx: &Context, route: Route, is_paused: bool) -> Result { let their_identifier = - if let Some(terminal) = ctx.find_terminal_address(route.clone()).await? { - SecureChannelMetadata::from_terminal_address(&terminal) + if let Some((_address, metadata)) = ctx.find_terminal_address(route.iter())? { + SecureChannelMetadata::from_terminal_address_metadata(&metadata) .map(|m| m.their_identifier()) .ok() } else { @@ -53,10 +53,10 @@ impl InletSharedState { self.route_index } - pub async fn update_route(&mut self, ctx: &Context, new_route: Route) -> Result<()> { + pub fn update_route(&mut self, ctx: &Context, new_route: Route) -> Result<()> { let their_identifier = - if let Some(terminal) = ctx.find_terminal_address(new_route.clone()).await? { - SecureChannelMetadata::from_terminal_address(&terminal) + if let Some((_address, metadata)) = ctx.find_terminal_address(new_route.iter())? { + SecureChannelMetadata::from_terminal_address_metadata(&metadata) .map(|m| m.their_identifier()) .ok() } else { diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/portal/interceptor.rs b/implementations/rust/ockam/ockam_transport_tcp/src/portal/interceptor.rs index cb44928531b..694b96ed69d 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/portal/interceptor.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/portal/interceptor.rs @@ -59,7 +59,7 @@ impl PortalOutletInterceptor { /// │Channel │ │ │ │Outlet │ /// └────────┘ └───────────┘ └────────┘ /// ``` - pub async fn create( + pub fn create( context: &Context, listener_address: Address, spawner_flow_control_id: Option, @@ -78,7 +78,6 @@ impl PortalOutletInterceptor { .with_address(listener_address) .with_incoming_access_control_arc(incoming_access_control) .start(context) - .await .map(|_| ()) } } @@ -110,8 +109,7 @@ impl Worker for PortalOutletInterceptor { self.incoming_access_control.clone(), self.outgoing_access_control.clone(), self.interceptor_factory.create(), - ) - .await?; + )?; // retrieve the flow id from the previous hop if it exists, usually a secure channel let source_flow_control_id = context @@ -124,10 +122,10 @@ impl Worker for PortalOutletInterceptor { // which was just created context .flow_controls() - .add_consumer(worker_address.clone(), source_flow_control_id); + .add_consumer(&worker_address, source_flow_control_id); } - message = message.push_front_onward_route(&worker_address); + message = message.push_front_onward_route(worker_address.clone()); trace!( "forwarding message: onward={:?}; return={:?}; worker={:?}", @@ -158,7 +156,7 @@ impl PortalInletInterceptor { /// │Inlet │ │ │ │Channel │ /// └────────┘ └───────────┘ └────────┘ /// ``` - pub async fn create( + pub fn create( context: &Context, listener_address: Address, interceptor_factory: Arc, @@ -171,7 +169,7 @@ impl PortalInletInterceptor { response_incoming_access_control, }; - context.start_worker(listener_address, worker).await + context.start_worker(listener_address, worker) } } @@ -201,7 +199,7 @@ impl Worker for PortalInletInterceptor { // Retrieve the flow id from the next hop if it exists let flow_control_id = context .flow_controls() - .find_flow_control_with_producer_address(&next_hop) + .find_flow_control_with_producer_address(next_hop) .map(|x| x.flow_control_id().clone()); let inlet_responder_address = message.return_route().next()?.clone(); @@ -213,10 +211,9 @@ impl Worker for PortalInletInterceptor { self.request_outgoing_access_control.clone(), self.response_incoming_access_control.clone(), self.interceptor_factory.create(), - ) - .await?; + )?; - message = message.push_front_onward_route(&worker_address); + message = message.push_front_onward_route(worker_address.clone()); trace!( "forwarding message: onward={:?}; return={:?}; worker={:?}", @@ -277,7 +274,7 @@ impl Worker for PortalInterceptorWorker { onward_route.clone(), return_route.clone(), &buffer, - &local_info, + local_info, ) .await?; } @@ -295,13 +292,11 @@ impl Worker for PortalInterceptorWorker { if !disconnect_received { debug!( "{:?} received disconnect event from {:?}", - context.address(), + context.primary_address(), return_route ); - context - .stop_worker(self.other_worker_address.clone()) - .await?; - context.stop_worker(context.address()).await?; + context.stop_address(&self.other_worker_address)?; + context.stop_address(context.primary_address())?; } } PortalMessage::Ping => self.forward(context, routed_message).await?, @@ -361,7 +356,7 @@ impl PortalInterceptorWorker { /// - `inlet_instance` the route from the interceptor to the inlet. /// - `incoming_access_control` is the access control for the incoming messages. /// - `outgoing_access_control` is the access control for the outgoing messages. - pub async fn create_inlet_interceptor( + pub fn create_inlet_interceptor( context: &mut Context, flow_control_id: Option, inlet_instance: Route, @@ -377,7 +372,7 @@ impl PortalInterceptorWorker { if let Some(flow_control_id) = flow_control_id { let flow_controls = context.flow_controls(); - flow_controls.add_consumer(from_outlet_worker_address.clone(), &flow_control_id); + flow_controls.add_consumer(&from_outlet_worker_address, &flow_control_id); } let from_outlet_worker = Self { @@ -391,8 +386,7 @@ impl PortalInterceptorWorker { WorkerBuilder::new(from_outlet_worker) .with_address(from_outlet_worker_address.clone()) .with_incoming_access_control_arc(incoming_access_control) - .start(context) - .await?; + .start(context)?; let from_inlet_worker = Self { other_worker_address: from_outlet_worker_address, @@ -405,8 +399,7 @@ impl PortalInterceptorWorker { WorkerBuilder::new(from_inlet_worker) .with_address(from_inlet_worker_address.clone()) .with_outgoing_access_control_arc(outgoing_access_control) - .start(context) - .await?; + .start(context)?; Ok(from_inlet_worker_address) } @@ -430,7 +423,7 @@ impl PortalInterceptorWorker { /// - `spawner_flow_control_id` to account for future created outlets, /// - `incoming_access_control` is the access control for the incoming messages. /// - `outgoing_access_control` is the access control for the outgoing messages. - async fn create_outlet_interceptor( + fn create_outlet_interceptor( context: &mut Context, outlet_route: Route, flow_control_id: FlowControlId, @@ -463,7 +456,7 @@ impl PortalInterceptorWorker { let flow_controls = context.flow_controls(); flow_controls.add_producer( - from_inlet_worker_address.clone(), + &from_inlet_worker_address, &flow_control_id, spawner_flow_control_id.as_ref(), vec![], @@ -481,8 +474,7 @@ impl PortalInterceptorWorker { flow_control_id.clone(), spawner_flow_control_id.clone(), ))) - .start(context) - .await?; + .start(context)?; // allow forwarding the `pong` message to the other worker let response_outgoing_access_control = { @@ -495,8 +487,7 @@ impl PortalInterceptorWorker { WorkerBuilder::new(from_outlet_worker) .with_address(from_outlet_worker_address) .with_outgoing_access_control(response_outgoing_access_control) - .start(context) - .await?; + .start(context)?; Ok(from_inlet_worker_address) } @@ -521,7 +512,7 @@ impl PortalInterceptorWorker { ); local_message .set_onward_route(fixed_onward_route.clone()) - .push_front_return_route(&self.other_worker_address) + .push_front_return_route(self.other_worker_address.clone()) } else { local_message = local_message.pop_front_onward_route()?; // Since we force the return route next step (fixed_onward_route in the other worker), @@ -556,11 +547,7 @@ impl PortalInterceptorWorker { if let Some(fixed_onward_route) = &self.fixed_onward_route { // To correctly proxy messages to the inlet or outlet side // we invert the return route when a message pass through - return_route = provided_return_route - .clone() - .modify() - .prepend(self.other_worker_address.clone()) - .into(); + return_route = self.other_worker_address.clone() + provided_return_route; onward_route = fixed_onward_route.clone(); } else { // Since we force the return route next step (fixed_onward_route in the other worker), diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/portal/options.rs b/implementations/rust/ockam/ockam_transport_tcp/src/portal/options.rs index 47aa7cc5397..bb45790cbc3 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/portal/options.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/portal/options.rs @@ -81,12 +81,12 @@ impl TcpInletOptions { addresses: &Addresses, next: &Address, ) { - Self::setup_flow_control_for_address(flow_controls, addresses.sender_remote.clone(), next) + Self::setup_flow_control_for_address(flow_controls, &addresses.sender_remote, next) } pub(crate) fn setup_flow_control_for_address( flow_controls: &FlowControls, - address: Address, + address: &Address, next: &Address, ) { if let Some(flow_control_id) = flow_controls @@ -182,7 +182,7 @@ impl TcpOutletOptions { address: &Address, ) { for id in &self.consumer { - flow_controls.add_consumer(address.clone(), id); + flow_controls.add_consumer(address, id); } } @@ -194,11 +194,8 @@ impl TcpOutletOptions { // Check if the Worker that send us this message is a Producer // If yes - outlet worker will be added to that flow control to be able to receive further // messages from that Producer - if let Some(producer_flow_control_id) = flow_controls - .get_flow_control_with_producer(src_addr) - .map(|x| x.flow_control_id().clone()) - { - flow_controls.add_consumer(addresses.sender_remote.clone(), &producer_flow_control_id); + if let Some(producer_info) = flow_controls.get_flow_control_with_producer(src_addr) { + flow_controls.add_consumer(&addresses.sender_remote, producer_info.flow_control_id()); } } } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/portal/outlet_listener.rs b/implementations/rust/ockam/ockam_transport_tcp/src/portal/outlet_listener.rs index 52d2666dabe..3a1ca2083d6 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/portal/outlet_listener.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/portal/outlet_listener.rs @@ -29,7 +29,7 @@ impl TcpOutletListenWorker { } #[instrument(skip_all, name = "TcpOutletListenWorker::start")] - pub(crate) async fn start( + pub(crate) fn start( ctx: &Context, registry: TcpRegistry, address: Address, @@ -45,8 +45,7 @@ impl TcpOutletListenWorker { .with_address(address) .with_incoming_access_control_arc(access_control) .with_outgoing_access_control(DenyAll) - .start(ctx) - .await?; + .start(ctx)?; Ok(()) } @@ -59,14 +58,16 @@ impl Worker for TcpOutletListenWorker { #[instrument(skip_all, name = "TcpOutletListenWorker::initialize")] async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.registry.add_outlet_listener_worker(&ctx.address()); + self.registry + .add_outlet_listener_worker(ctx.primary_address()); Ok(()) } #[instrument(skip_all, name = "TcpOutletListenWorker::shutdown")] async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.registry.remove_outlet_listener_worker(&ctx.address()); + self.registry + .remove_outlet_listener_worker(ctx.primary_address()); Ok(()) } @@ -104,8 +105,7 @@ impl Worker for TcpOutletListenWorker { addresses.clone(), self.options.incoming_access_control.clone(), self.options.outgoing_access_control.clone(), - ) - .await?; + )?; debug!("Created Tcp Outlet at {}", addresses.sender_remote); diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_receiver.rs b/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_receiver.rs index 6210a023038..27da7989f4c 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_receiver.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_receiver.rs @@ -52,7 +52,8 @@ impl Processor for TcpPortalRecvPr #[instrument(skip_all, name = "TcpPortalRecvProcessor::initialize")] async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.registry.add_portal_receiver_processor(&ctx.address()); + self.registry + .add_portal_receiver_processor(ctx.primary_address()); Ok(()) } @@ -60,7 +61,7 @@ impl Processor for TcpPortalRecvPr #[instrument(skip_all, name = "TcpPortalRecvProcessor::shutdown")] async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { self.registry - .remove_portal_receiver_processor(&ctx.address()); + .remove_portal_receiver_processor(ctx.primary_address()); Ok(()) } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_worker.rs b/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_worker.rs index ef4c9f5049a..7ebc41e159a 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_worker.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_worker.rs @@ -68,7 +68,7 @@ impl TcpPortalWorker { /// Start a new `TcpPortalWorker` of type [`TypeName::Inlet`] #[instrument(skip_all)] #[allow(clippy::too_many_arguments)] - pub(super) async fn start_new_inlet( + pub(super) fn start_new_inlet( ctx: &Context, registry: TcpRegistry, streams: (ReadHalfMaybeTls, WriteHalfMaybeTls), @@ -91,13 +91,12 @@ impl TcpPortalWorker { incoming_access_control, outgoing_access_control, ) - .await } /// Start a new `TcpPortalWorker` of type [`TypeName::Outlet`] #[allow(clippy::too_many_arguments)] #[instrument(skip_all)] - pub(super) async fn start_new_outlet( + pub(super) fn start_new_outlet( ctx: &Context, registry: TcpRegistry, hostname_port: HostnamePort, @@ -120,13 +119,12 @@ impl TcpPortalWorker { incoming_access_control, outgoing_access_control, ) - .await } /// Start a new `TcpPortalWorker` #[allow(clippy::too_many_arguments)] #[instrument(skip_all)] - async fn start( + fn start( ctx: &Context, registry: TcpRegistry, hostname_port: HostnamePort, @@ -177,12 +175,14 @@ impl TcpPortalWorker { let internal_mailbox = Mailbox::new( addresses.sender_internal, + None, Arc::new(AllowSourceAddress(addresses.receiver_internal)), Arc::new(DenyAll), ); let remote_mailbox = Mailbox::new( addresses.sender_remote, + None, incoming_access_control, outgoing_access_control, ); @@ -190,8 +190,7 @@ impl TcpPortalWorker { // start worker WorkerBuilder::new(worker) .with_mailboxes(Mailboxes::new(internal_mailbox, vec![remote_mailbox])) - .start(ctx) - .await?; + .start(ctx)?; Ok(()) } @@ -211,11 +210,11 @@ impl TcpPortalWorker { /// Start a `TcpPortalRecvProcessor` #[instrument(skip_all)] - async fn start_receiver(&mut self, ctx: &Context, onward_route: Route) -> Result<()> { + fn start_receiver(&mut self, ctx: &Context, onward_route: Route) -> Result<()> { if let Some(rx) = self.read_half.take() { match rx { - ReadHalfNoTls(rx) => self.start_receive_processor(ctx, onward_route, rx).await, - ReadHalfWithTls(rx) => self.start_receive_processor(ctx, onward_route, rx).await, + ReadHalfNoTls(rx) => self.start_receive_processor(ctx, onward_route, rx), + ReadHalfWithTls(rx) => self.start_receive_processor(ctx, onward_route, rx), } } else { Err(TransportError::PortalInvalidState)? @@ -223,7 +222,7 @@ impl TcpPortalWorker { } /// Start a TcpPortalRecvProcessor using a specific AsyncRead implementation (either supporting TLS or not) - async fn start_receive_processor( + fn start_receive_processor( &mut self, ctx: &Context, onward_route: Route, @@ -238,20 +237,21 @@ impl TcpPortalWorker { let remote = Mailbox::new( self.addresses.receiver_remote.clone(), + None, Arc::new(DenyAll), self.outgoing_access_control.clone(), ); let internal = Mailbox::new( self.addresses.receiver_internal.clone(), + None, Arc::new(DenyAll), Arc::new(AllowOnwardAddress(self.addresses.sender_internal.clone())), ); ProcessorBuilder::new(receiver) .with_mailboxes(Mailboxes::new(remote, vec![internal])) - .start(ctx) - .await?; + .start(ctx)?; Ok(()) } @@ -278,12 +278,8 @@ impl TcpPortalWorker { } #[instrument(skip_all)] - async fn stop_receiver(&self, ctx: &Context) -> Result<()> { - if ctx - .stop_processor(self.addresses.receiver_remote.clone()) - .await - .is_ok() - { + fn stop_receiver(&self, ctx: &Context) -> Result<()> { + if ctx.stop_address(&self.addresses.receiver_remote).is_ok() { debug!( "{:?} at: {} stopped receiver due to connection drop", self.portal_type.str(), @@ -295,9 +291,8 @@ impl TcpPortalWorker { } #[instrument(skip_all)] - async fn stop_sender(&self, ctx: &Context) -> Result<()> { - ctx.stop_worker(self.addresses.sender_internal.clone()) - .await + fn stop_sender(&self, ctx: &Context) -> Result<()> { + ctx.stop_address(&self.addresses.sender_internal) } /// Start the portal disconnection process @@ -314,20 +309,20 @@ impl TcpPortalWorker { // connection and shut down both processor and worker DisconnectionReason::FailedTx => { self.notify_remote_about_disconnection(ctx).await?; - self.stop_receiver(ctx).await?; + self.stop_receiver(ctx)?; // Sleep, so that if connection is dropped on both sides at the same time, the other // side had time to notify us about the closure. Otherwise, the message won't be // delivered which can lead to a warning message from a secure channel (or whatever // is used to deliver the message). Can be removed though ctx.sleep(Duration::from_secs(2)).await; - self.stop_sender(ctx).await?; + self.stop_sender(ctx)?; } // Packets were dropped while traveling to us, let's notify the other end about dropped // connection and DisconnectionReason::InvalidCounter => { self.notify_remote_about_disconnection(ctx).await?; - self.stop_receiver(ctx).await?; - self.stop_sender(ctx).await?; + self.stop_receiver(ctx)?; + self.stop_sender(ctx)?; } // We couldn't read data from the tcp connection // Receiver should have already notified the other end and should shut down itself @@ -337,13 +332,13 @@ impl TcpPortalWorker { // delivered which can lead to a warning message from a secure channel (or whatever // is used to deliver the message). Can be removed though ctx.sleep(Duration::from_secs(2)).await; - self.stop_sender(ctx).await?; + self.stop_sender(ctx)?; } // Other end notifies us that the tcp connection is dropped // Let's shut down both processor and worker DisconnectionReason::Remote => { - self.stop_receiver(ctx).await?; - self.stop_sender(ctx).await?; + self.stop_receiver(ctx)?; + self.stop_sender(ctx)?; } } @@ -399,7 +394,7 @@ impl TcpPortalWorker { ) .await?; - self.start_receiver(ctx, pong_route.clone()).await?; + self.start_receiver(ctx, pong_route.clone())?; debug!( "Outlet at: {} successfully connected", @@ -494,7 +489,7 @@ impl Worker for TcpPortalWorker { if PortalMessage::decode(&payload)? != PortalMessage::Pong { return Err(TransportError::Protocol)?; }; - self.handle_receive_pong(ctx, return_route).await + self.handle_receive_pong(ctx, return_route) } State::Initialized => { trace!( @@ -536,8 +531,8 @@ impl Worker for TcpPortalWorker { impl TcpPortalWorker { #[instrument(skip_all)] - async fn handle_receive_pong(&mut self, ctx: &Context, return_route: Route) -> Result<()> { - self.start_receiver(ctx, return_route.clone()).await?; + fn handle_receive_pong(&mut self, ctx: &Context, return_route: Route) -> Result<()> { + self.start_receiver(ctx, return_route.clone())?; debug!("Inlet at: {} received pong", self.addresses.sender_internal); self.remote_route = Some(return_route); self.state = State::Initialized; diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/ebpf_support.rs b/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/ebpf_support.rs index 5f06577750a..c074de2aa34 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/ebpf_support.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/ebpf_support.rs @@ -164,8 +164,7 @@ impl TcpTransportEbpfSupport { *tcp_packet_writer_lock = Some(tcp_packet_writer.create_new_box()); - ctx.start_processor(self.raw_socket_processor_address.clone(), processor) - .await?; + ctx.start_processor(self.raw_socket_processor_address.clone(), processor)?; info!("Started RawSocket for protocol: {}", self.ip_proto); diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/privileged_portals.rs b/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/privileged_portals.rs index 93b73a65326..0c25aba04e6 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/privileged_portals.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/privileged_portals.rs @@ -6,12 +6,12 @@ use caps::{CapSet, Capability}; use core::fmt::Debug; use log::{debug, error}; use nix::unistd::Uid; +use ockam_core::compat::sync::{Arc, RwLock as SyncRwLock}; use ockam_core::{Address, DenyAll, Result, Route}; -use ockam_node::compat::asynchronous::{resolve_peer, RwLock}; +use ockam_node::compat::asynchronous::resolve_peer; use ockam_node::{ProcessorBuilder, WorkerBuilder}; use ockam_transport_core::{HostnamePort, TransportError}; use std::net::IpAddr; -use std::sync::Arc; use tokio::net::TcpListener; use tokio::sync::mpsc::channel; use tracing::instrument; @@ -90,16 +90,15 @@ impl TcpTransport { let tcp_packet_writer = self.start_raw_socket_processor_if_needed().await?; - let inlet_shared_state = - InletSharedState::create(self.ctx(), outlet_route.clone(), false).await?; - let inlet_shared_state = Arc::new(RwLock::new(inlet_shared_state)); + let inlet_shared_state = InletSharedState::create(self.ctx(), outlet_route.clone(), false)?; + let inlet_shared_state = Arc::new(SyncRwLock::new(inlet_shared_state)); let remote_worker_address = Address::random_tagged("Ebpf.RemoteWorker.Inlet"); let internal_worker_address = Address::random_tagged("Ebpf.InternalWorker.Inlet"); TcpInletOptions::setup_flow_control_for_address( self.ctx().flow_controls(), - remote_worker_address.clone(), + &remote_worker_address, &next, ); @@ -125,16 +124,14 @@ impl TcpTransport { .with_address(remote_worker_address.clone()) .with_incoming_access_control_arc(options.incoming_access_control) .with_outgoing_access_control(DenyAll) - .start(self.ctx()) - .await?; + .start(self.ctx())?; let internal_worker = InternalProcessor::new_inlet(receiver, inlet_info); ProcessorBuilder::new(internal_worker) .with_address(internal_worker_address.clone()) .with_incoming_access_control(DenyAll) .with_outgoing_access_control_arc(options.outgoing_access_control) - .start(self.ctx()) - .await?; + .start(self.ctx())?; Ok(TcpInlet::new_privileged( local_address, @@ -145,7 +142,7 @@ impl TcpTransport { /// Stop the Privileged Inlet #[instrument(skip(self), fields(port=port))] - pub async fn stop_privileged_inlet(&self, port: Port) -> Result<()> { + pub fn stop_privileged_inlet(&self, port: Port) -> Result<()> { self.ebpf_support.inlet_registry.delete_inlet(port); Ok(()) @@ -209,27 +206,22 @@ impl TcpTransport { .with_address(remote_worker_address) .with_incoming_access_control_arc(options.incoming_access_control) .with_outgoing_access_control(DenyAll) - .start(self.ctx()) - .await?; + .start(self.ctx())?; let internal_worker = InternalProcessor::new_outlet(receiver, outlet_info); ProcessorBuilder::new(internal_worker) .with_address(internal_worker_address) .with_incoming_access_control(DenyAll) .with_outgoing_access_control_arc(options.outgoing_access_control) - .start(self.ctx()) - .await?; + .start(self.ctx())?; Ok(()) } /// Stop the Privileged Inlet - #[instrument(skip(self), fields(address = % addr.clone().into()))] - pub async fn stop_privileged_outlet( - &self, - addr: impl Into
+ Clone + Debug, - ) -> Result<()> { - self.ctx().stop_worker(addr).await?; + #[instrument(skip(self), fields(address = % address))] + pub fn stop_privileged_outlet(&self, address: &Address) -> Result<()> { + self.ctx().stop_address(address)?; // TODO: eBPF Remove from the registry // self.ebpf_support.outlet_registry diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/registry/inlet.rs b/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/registry/inlet.rs index 628c4edfbfe..9fbc71e4d44 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/registry/inlet.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/registry/inlet.rs @@ -1,10 +1,8 @@ use crate::portal::InletSharedState; use crate::privileged_portal::packet::RawSocketReadResult; use crate::privileged_portal::{ConnectionIdentifier, Port}; -use ockam_core::compat::sync::Arc; -use ockam_core::compat::sync::RwLock as SyncRwLock; +use ockam_core::compat::sync::{Arc, RwLock as SyncRwLock}; use ockam_core::{Address, LocalInfoIdentifier}; -use ockam_node::compat::asynchronous::RwLock as AsyncRwLock; use std::collections::HashMap; use std::net::Ipv4Addr; use tokio::net::TcpListener; @@ -32,7 +30,7 @@ impl InletRegistry { sender: Sender, port: Port, tcp_listener: TcpListener, - inlet_shared_state: Arc>, + inlet_shared_state: Arc>, ) -> Inlet { let mut inlets = self.inlets.write().unwrap(); @@ -72,7 +70,7 @@ pub struct Inlet { /// Port pub port: Port, /// Route to the corresponding Outlet - pub inlet_shared_state: Arc>, + pub inlet_shared_state: Arc>, /// Hold to mark the port as taken pub _tcp_listener: Arc, /// Same map with different key diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/workers/internal_processor.rs b/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/workers/internal_processor.rs index 70528406221..bcd15dcc3cb 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/workers/internal_processor.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/privileged_portal/workers/internal_processor.rs @@ -72,7 +72,7 @@ impl Processor for InternalProcessor { match &self.mode { // Client -> Inlet packet PortalMode::Inlet { inlet } => { - let inlet_shared_state = inlet.inlet_shared_state.read().await.clone(); + let inlet_shared_state = inlet.inlet_shared_state.read().unwrap().clone(); if inlet_shared_state.is_paused() { return Ok(true); @@ -133,7 +133,7 @@ impl Processor for InternalProcessor { .with_onward_route(inlet_shared_state.route().clone()) .with_return_route(route![inlet.remote_worker_address.clone()]) .with_payload(cbor_encode_preallocate(&portal_packet)?), - ctx.address(), + ctx.primary_address().clone(), ) .await?; } @@ -174,7 +174,7 @@ impl Processor for InternalProcessor { .with_onward_route(return_route) .with_return_route(route![outlet.remote_worker_address.clone()]) .with_payload(cbor_encode_preallocate(&portal_packet)?), - ctx.address(), + ctx.primary_address().clone(), ) .await?; } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/transport/connection.rs b/implementations/rust/ockam/ockam_transport_tcp/src/transport/connection.rs index 12ea8729c50..8081814fe8d 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/transport/connection.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/transport/connection.rs @@ -38,6 +38,12 @@ impl From for Address { } } +impl AsRef
for TcpConnection { + fn as_ref(&self) -> &Address { + self.sender_address() + } +} + impl TcpConnection { /// Constructor pub fn new( @@ -58,8 +64,8 @@ impl TcpConnection { /// Stops the [`TcpConnection`], this method must be called to avoid /// leakage of the connection. /// Simply dropping this object won't close the connection - pub async fn stop(&self, context: &Context) -> Result<()> { - context.stop_worker(self.sender_address.clone()).await + pub fn stop(&self, context: &Context) -> Result<()> { + context.stop_address(&self.sender_address) } /// Corresponding [`TcpSendWorker`](super::workers::TcpSendWorker) [`Address`] that can be used /// in a route to send messages to the other side of the TCP connection @@ -92,7 +98,7 @@ impl TcpTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let tcp = TcpTransport::create(&ctx).await?; + /// let tcp = TcpTransport::create(&ctx)?; /// tcp.listen("127.0.0.1:8000", TcpListenerOptions::new()).await?; // Listen on port 8000 /// let connection = tcp.connect("127.0.0.1:5000", TcpConnectionOptions::new()).await?; // and connect to port 5000 /// # Ok(()) } @@ -126,8 +132,7 @@ impl TcpTransport { socket, mode, &flow_control_id, - ) - .await?; + )?; TcpRecvProcessor::start( &self.ctx, @@ -138,8 +143,7 @@ impl TcpTransport { mode, &flow_control_id, receiver_outgoing_access_control, - ) - .await?; + )?; Ok(TcpConnection::new( addresses.sender_address().clone(), @@ -151,7 +155,7 @@ impl TcpTransport { } /// Interrupt an active TCP connection given its Sender `Address` - pub async fn disconnect(&self, address: impl Into
) -> Result<()> { - self.ctx.stop_worker(address.into()).await + pub fn disconnect(&self, address: impl AsRef
) -> Result<()> { + self.ctx.stop_address(address.as_ref()) } } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/transport/lifecycle.rs b/implementations/rust/ockam/ockam_transport_tcp/src/transport/lifecycle.rs index 96e555c1019..59bb8c88567 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/transport/lifecycle.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/transport/lifecycle.rs @@ -1,5 +1,5 @@ use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{async_trait, Address, AsyncTryClone, Error, Result, TransportType}; +use ockam_core::{async_trait, Address, Error, Result, TransportType, TryClone}; use ockam_node::Context; use ockam_transport_core::Transport; use std::net::SocketAddr; @@ -16,12 +16,12 @@ impl TcpTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let tcp = TcpTransport::create(&ctx).await?; + /// let tcp = TcpTransport::create(&ctx)?; /// # Ok(()) } /// ``` #[instrument(name = "create tcp transport", skip_all)] - pub async fn create(ctx: &Context) -> Result { - let tcp = Self::new(ctx.async_try_clone().await?); + pub fn create(ctx: &Context) -> Result { + let tcp = Self::new(ctx.try_clone()?); // make the TCP transport available in the list of supported transports for // later address resolution when socket addresses will need to be instantiated as TCP // worker addresses @@ -111,7 +111,7 @@ impl Transport for TcpTransport { TCP } - async fn resolve_address(&self, address: Address) -> Result
{ + async fn resolve_address(&self, address: &Address) -> Result
{ if address.transport_type() == TCP { Ok(self .connect(address.address().to_string(), TcpConnectionOptions::new()) @@ -129,8 +129,8 @@ impl Transport for TcpTransport { } } - async fn disconnect(&self, address: Address) -> Result<()> { - self.disconnect(address).await + fn disconnect(&self, address: &Address) -> Result<()> { + self.disconnect(address) } } @@ -143,9 +143,9 @@ mod tests { #[ockam_macros::test] async fn test_resolve_address(ctx: &mut Context) -> Result<()> { - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let tcp_address = "127.0.0.1:0"; - let initial_workers = ctx.list_workers(); + let initial_workers = ctx.list_workers()?; let listener = TcpListener::bind(tcp_address) .await .map_err(TransportError::from)?; @@ -159,11 +159,11 @@ mod tests { }); let resolved = tcp - .resolve_address(Address::new_with_string(TCP, local_address.clone())) + .resolve_address(&Address::new_with_string(TCP, local_address.clone())) .await?; // there are 2 additional workers - let mut additional_workers = ctx.list_workers(); + let mut additional_workers = ctx.list_workers()?; additional_workers.retain(|w| !initial_workers.contains(w)); assert_eq!(additional_workers.len(), 2); @@ -172,7 +172,7 @@ mod tests { // trying to resolve the address a second time should still work let _route = tcp - .resolve_address(Address::new_with_string(TCP, local_address)) + .resolve_address(&Address::new_with_string(TCP, local_address)) .await?; tokio::time::sleep(Duration::from_millis(250)).await; @@ -182,7 +182,7 @@ mod tests { #[ockam_macros::test] async fn test_resolve_route_with_dns_address(ctx: &mut Context) -> Result<()> { - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let tcp_address = "127.0.0.1:0"; let listener = TcpListener::bind(tcp_address) .await @@ -196,7 +196,7 @@ mod tests { }); let result = tcp - .resolve_address(Address::new_with_string( + .resolve_address(&Address::new_with_string( TCP, format!("localhost:{}", socket_address.port()), )) diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/transport/listener.rs b/implementations/rust/ockam/ockam_transport_tcp/src/transport/listener.rs index 1f2b7d8647d..1f6954fedd1 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/transport/listener.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/transport/listener.rs @@ -69,7 +69,7 @@ impl TcpTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let tcp = TcpTransport::create(&ctx).await?; + /// let tcp = TcpTransport::create(&ctx)?; /// tcp.listen("127.0.0.1:8000", TcpListenerOptions::new()).await?; /// # Ok(()) } pub async fn listen( @@ -87,7 +87,7 @@ impl TcpTransport { } /// Interrupt an active TCP listener given its `Address` - pub async fn stop_listener(&self, address: &Address) -> Result<()> { - self.ctx.stop_processor(address.clone()).await + pub fn stop_listener(&self, address: &Address) -> Result<()> { + self.ctx.stop_address(address) } } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/transport/mod.rs b/implementations/rust/ockam/ockam_transport_tcp/src/transport/mod.rs index d87485c8fd7..4e67d9204c4 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/transport/mod.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/transport/mod.rs @@ -13,7 +13,7 @@ pub use portals::*; use crate::TcpRegistry; use ockam_core::compat::sync::Arc; -use ockam_core::{async_trait, Result}; +use ockam_core::Result; use ockam_node::{Context, HasContext}; /// High level management interface for TCP transports @@ -36,7 +36,7 @@ use ockam_node::{Context, HasContext}; /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { -/// let tcp = TcpTransport::create(&ctx).await?; +/// let tcp = TcpTransport::create(&ctx)?; /// tcp.listen("127.0.0.1:8000", TcpListenerOptions::new()).await?; // Listen on port 8000 /// tcp.connect("127.0.0.1:5000", TcpConnectionOptions::new()).await?; // And connect to port 5000 /// # Ok(()) } @@ -49,7 +49,7 @@ use ockam_node::{Context, HasContext}; /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { -/// let tcp = TcpTransport::create(&ctx).await?; +/// let tcp = TcpTransport::create(&ctx)?; /// tcp.listen("127.0.0.1:8000", TcpListenerOptions::new()).await?; // Listen on port 8000 /// tcp.listen("127.0.0.1:9000", TcpListenerOptions::new()).await?; // Listen on port 9000 /// # Ok(()) } @@ -77,11 +77,10 @@ impl TcpTransport { /// This trait adds a `create_tcp_transport` method to any struct returning a Context. /// This is the case for an ockam::Node, so you can write `node.create_tcp_transport()` -#[async_trait] pub trait TcpTransportExtension: HasContext { /// Create a TCP transport - async fn create_tcp_transport(&self) -> Result { - TcpTransport::create(self.get_context()).await + fn create_tcp_transport(&self) -> Result { + TcpTransport::create(self.get_context()) } } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/transport/portals.rs b/implementations/rust/ockam/ockam_transport_tcp/src/transport/portals.rs index 9909ff6549d..da410fcfe21 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/transport/portals.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/transport/portals.rs @@ -3,10 +3,9 @@ use crate::{portal::TcpOutletListenWorker, TcpInletOptions, TcpOutletOptions, Tc use core::fmt; use core::fmt::{Debug, Formatter}; use ockam_core::compat::net::SocketAddr; -use ockam_core::compat::sync::Arc; +use ockam_core::compat::sync::{Arc, RwLock as SyncRwLock}; use ockam_core::flow_control::FlowControls; -use ockam_core::{route, Address, Result, Route}; -use ockam_node::compat::asynchronous::RwLock; +use ockam_core::{Address, Result, Route}; use ockam_node::Context; use ockam_transport_core::{parse_socket_addr, HostnamePort}; use tracing::instrument; @@ -20,13 +19,14 @@ impl TcpTransport { /// ```rust /// use ockam_transport_tcp::{TcpInletOptions, TcpTransport}; /// # use ockam_node::Context; - /// # use ockam_core::{AllowAll, Result, route}; + /// # use ockam_core::{AllowAll, Result, route, Address}; /// # async fn test(ctx: Context) -> Result<()> { /// let route_path = route!["outlet"]; /// - /// let tcp = TcpTransport::create(&ctx).await?; - /// tcp.create_inlet("inlet", route_path, TcpInletOptions::new()).await?; - /// # tcp.stop_inlet("inlet").await?; + /// let tcp = TcpTransport::create(&ctx)?; + /// let address: Address = "inlet".into(); + /// tcp.create_inlet(address.clone(), route_path, TcpInletOptions::new()).await?; + /// # tcp.stop_inlet(&address)?; /// # Ok(()) } /// ``` #[instrument(skip(self), fields(address = ? bind_addr.clone().into(), outlet_route = ? outlet_route.clone()))] @@ -52,18 +52,19 @@ impl TcpTransport { /// ```rust /// use ockam_transport_tcp::{TcpInletOptions, TcpTransport}; /// # use ockam_node::Context; - /// # use ockam_core::{AllowAll, Result, route}; + /// # use ockam_core::{AllowAll, Result, route, Address}; /// # async fn test(ctx: Context) -> Result<()> { /// let route = route!["outlet"]; /// - /// let tcp = TcpTransport::create(&ctx).await?; - /// tcp.create_inlet("inlet", route, TcpInletOptions::new()).await?; - /// tcp.stop_inlet("inlet").await?; + /// let tcp = TcpTransport::create(&ctx)?; + /// let address: Address = "inlet".into(); + /// tcp.create_inlet(address.clone(), route, TcpInletOptions::new()).await?; + /// tcp.stop_inlet(&address)?; /// # Ok(()) } /// ``` - #[instrument(skip(self), fields(address = ? addr.clone().into()))] - pub async fn stop_inlet(&self, addr: impl Into
+ Clone + Debug) -> Result<()> { - self.ctx.stop_processor(addr).await?; + #[instrument(skip(self), fields(address = ? address))] + pub fn stop_inlet(&self, address: &Address) -> Result<()> { + self.ctx.stop_address(address)?; Ok(()) } @@ -77,18 +78,19 @@ impl TcpTransport { /// ```rust /// use ockam_transport_tcp::{TcpOutletOptions, TcpTransport}; /// # use ockam_node::Context; - /// # use ockam_core::{AllowAll, Result}; + /// # use ockam_core::{Address, AllowAll, Result}; /// # use ockam_transport_core::HostnamePort; /// /// async fn test(ctx: Context) -> Result<()> { /// - /// let tcp = TcpTransport::create(&ctx).await?; - /// tcp.create_outlet("outlet", HostnamePort::new("localhost", 9000), TcpOutletOptions::new()).await?; - /// # tcp.stop_outlet("outlet").await?; + /// let tcp = TcpTransport::create(&ctx)?; + /// let address: Address = "outlet".into(); + /// tcp.create_outlet(address.clone(), HostnamePort::new("localhost", 9000), TcpOutletOptions::new())?; + /// # tcp.stop_outlet(&address)?; /// # Ok(()) } /// ``` #[instrument(skip(self), fields(address = ? address.clone().into(), peer=peer.clone().to_string()))] - pub async fn create_outlet( + pub fn create_outlet( &self, address: impl Into
+ Clone + Debug, peer: HostnamePort, @@ -100,8 +102,7 @@ impl TcpTransport { address.into(), peer, options, - ) - .await?; + )?; Ok(()) } @@ -110,20 +111,20 @@ impl TcpTransport { /// ```rust /// use ockam_transport_tcp::{TcpOutletOptions, TcpTransport}; /// # use ockam_node::Context; - /// # use ockam_core::{AllowAll, Result}; + /// # use ockam_core::{Address, AllowAll, Result}; /// # use ockam_transport_core::HostnamePort; /// /// async fn test(ctx: Context) -> Result<()> { /// - /// let tcp = TcpTransport::create(&ctx).await?; - /// tcp.create_outlet("outlet", HostnamePort::new("127.0.0.1", 5000), TcpOutletOptions::new()).await?; - /// tcp.stop_outlet("outlet").await?; + /// let tcp = TcpTransport::create(&ctx)?; + /// let address: Address = "outlet".into(); + /// tcp.create_outlet(address.clone(), HostnamePort::new("127.0.0.1", 5000), TcpOutletOptions::new())?; + /// tcp.stop_outlet(&address)?; /// # Ok(()) } /// ``` - #[instrument(skip(self), fields(address = % addr.clone().into()))] - pub async fn stop_outlet(&self, addr: impl Into
+ Clone + Debug) -> Result<()> { - self.ctx.stop_worker(addr).await?; - Ok(()) + #[instrument(skip(self), fields(address = % address))] + pub fn stop_outlet(&self, address: &Address) -> Result<()> { + self.ctx.stop_address(address) } } @@ -131,7 +132,7 @@ impl TcpTransport { #[derive(Clone, Debug)] pub struct TcpInlet { socket_address: SocketAddr, - inlet_shared_state: Arc>, + inlet_shared_state: Arc>, state: TcpInletState, } @@ -169,7 +170,7 @@ impl TcpInlet { pub fn new_regular( socket_address: SocketAddr, processor_address: Address, - inlet_shared_state: Arc>, + inlet_shared_state: Arc>, ) -> Self { Self { socket_address, @@ -182,7 +183,7 @@ impl TcpInlet { pub fn new_privileged( socket_address: SocketAddr, portal_worker_address: Address, - inlet_shared_state: Arc>, + inlet_shared_state: Arc>, ) -> Self { Self { socket_address, @@ -212,8 +213,7 @@ impl TcpInlet { } fn build_new_full_route(new_route: Route, old_route: &Route) -> Result { - let their_outlet_address = old_route.recipient()?; - Ok(route![new_route, their_outlet_address.clone()]) + Ok(new_route + old_route.recipient()?.clone()) } /// Update the route to the outlet node. @@ -223,12 +223,12 @@ impl TcpInlet { /// only newly accepted connections will use the new route. /// For privileged Portals old connections can continue work in case the Identifier of the /// Outlet node didn't change - pub async fn update_outlet_node_route(&self, ctx: &Context, new_route: Route) -> Result<()> { - let mut inlet_shared_state = self.inlet_shared_state.write().await; + pub fn update_outlet_node_route(&self, ctx: &Context, new_route: Route) -> Result<()> { + let mut inlet_shared_state = self.inlet_shared_state.write().unwrap(); let new_route = Self::build_new_full_route(new_route, inlet_shared_state.route())?; let next = new_route.next()?.clone(); - inlet_shared_state.update_route(ctx, new_route).await?; + inlet_shared_state.update_route(ctx, new_route)?; self.update_flow_controls(ctx.flow_controls(), next); @@ -236,8 +236,8 @@ impl TcpInlet { } /// Pause TCP Inlet, all incoming TCP streams will be dropped. - pub async fn pause(&self) { - let mut inlet_shared_state = self.inlet_shared_state.write().await; + pub fn pause(&self) { + let mut inlet_shared_state = self.inlet_shared_state.write().unwrap(); inlet_shared_state.set_is_paused(true); } @@ -249,7 +249,7 @@ impl TcpInlet { } => { TcpInletOptions::setup_flow_control_for_address( flow_controls, - portal_worker_address.clone(), + portal_worker_address, &next, ); } @@ -258,13 +258,13 @@ impl TcpInlet { } /// Unpause TCP Inlet and update the outlet route. - pub async fn unpause(&self, ctx: &Context, new_route: Route) -> Result<()> { - let mut inlet_shared_state = self.inlet_shared_state.write().await; + pub fn unpause(&self, ctx: &Context, new_route: Route) -> Result<()> { + let mut inlet_shared_state = self.inlet_shared_state.write().unwrap(); let new_route = Self::build_new_full_route(new_route, inlet_shared_state.route())?; let next = new_route.next()?.clone(); - inlet_shared_state.update_route(ctx, new_route).await?; + inlet_shared_state.update_route(ctx, new_route)?; inlet_shared_state.set_is_paused(false); self.update_flow_controls(ctx.flow_controls(), next); @@ -273,13 +273,13 @@ impl TcpInlet { } /// Stop the Inlet - pub async fn stop(&self, ctx: &Context) -> Result<()> { + pub fn stop(&self, ctx: &Context) -> Result<()> { match &self.state { TcpInletState::Privileged { .. } => { // TODO: eBPF } TcpInletState::Regular { processor_address } => { - ctx.stop_processor(processor_address.clone()).await?; + ctx.stop_address(processor_address)?; } } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/workers/listener.rs b/implementations/rust/ockam/ockam_transport_tcp/src/workers/listener.rs index 39034526dfd..11a1d4d4fec 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/workers/listener.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/workers/listener.rs @@ -2,7 +2,7 @@ use crate::workers::{Addresses, TcpRecvProcessor}; use crate::{TcpConnectionMode, TcpListenerInfo, TcpListenerOptions, TcpRegistry, TcpSendWorker}; use ockam_core::{async_trait, compat::net::SocketAddr}; use ockam_core::{Address, Processor, Result}; -use ockam_node::Context; +use ockam_node::{Context, ProcessorBuilder, WorkerShutdownPriority}; use ockam_transport_core::TransportError; use tokio::net::TcpListener; use tracing::{debug, instrument}; @@ -43,7 +43,10 @@ impl TcpListenProcessor { options, }; - ctx.start_processor(address.clone(), processor).await?; + ProcessorBuilder::new(processor) + .with_address(address.clone()) + .with_shutdown_priority(WorkerShutdownPriority::Priority5) + .start(ctx)?; Ok((saddr, address)) } @@ -55,10 +58,8 @@ impl Processor for TcpListenProcessor { #[instrument(skip_all, name = "TcpListenProcessor::initialize")] async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await?; - self.registry.add_listener_processor(TcpListenerInfo::new( - ctx.address(), + ctx.primary_address().clone(), self.socket_address, self.options.flow_control_id.clone(), )); @@ -68,7 +69,8 @@ impl Processor for TcpListenProcessor { #[instrument(skip_all, name = "TcpListenProcessor::shutdown")] async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.registry.remove_listener_processor(&ctx.address()); + self.registry + .remove_listener_processor(ctx.primary_address()); Ok(()) } @@ -104,8 +106,7 @@ impl Processor for TcpListenProcessor { peer, mode, &receiver_flow_control_id, - ) - .await?; + )?; // Processor to receive messages over the wire and forward them to the node TcpRecvProcessor::start( @@ -117,8 +118,7 @@ impl Processor for TcpListenProcessor { mode, &receiver_flow_control_id, receiver_outgoing_access_control, - ) - .await?; + )?; Ok(true) } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/workers/receiver.rs b/implementations/rust/ockam/ockam_transport_tcp/src/workers/receiver.rs index 13b8e969319..216a13a55f8 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/workers/receiver.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/workers/receiver.rs @@ -13,7 +13,7 @@ use ockam_core::{ OutgoingAccessControl, }; use ockam_core::{Processor, Result}; -use ockam_node::{Context, ProcessorBuilder}; +use ockam_node::{Context, ProcessorBuilder, WorkerShutdownPriority}; use ockam_transport_core::TransportError; use tokio::{io::AsyncReadExt, net::tcp::OwnedReadHalf}; use tracing::{info, instrument, trace}; @@ -59,7 +59,7 @@ impl TcpRecvProcessor { #[allow(clippy::too_many_arguments)] #[instrument(skip_all, name = "TcpRecvProcessor::start")] - pub async fn start( + pub fn start( ctx: &Context, registry: TcpRegistry, read_half: OwnedReadHalf, @@ -80,11 +80,13 @@ impl TcpRecvProcessor { let mailbox = Mailbox::new( addresses.receiver_address().clone(), + None, Arc::new(DenyAll), receiver_outgoing_access_control, ); let internal = Mailbox::new( addresses.receiver_internal_address().clone(), + None, Arc::new(DenyAll), Arc::new(AllowOnwardAddress( addresses.sender_internal_address().clone(), @@ -92,8 +94,8 @@ impl TcpRecvProcessor { ); ProcessorBuilder::new(receiver) .with_mailboxes(Mailboxes::new(mailbox, vec![internal])) - .start(ctx) - .await?; + .with_shutdown_priority(WorkerShutdownPriority::Priority1) + .start(ctx)?; Ok(()) } @@ -119,10 +121,8 @@ impl Processor for TcpRecvProcessor { #[instrument(skip_all, name = "TcpRecvProcessor::initialize")] async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await?; - self.registry.add_receiver_processor(TcpReceiverInfo::new( - ctx.address(), + ctx.primary_address().clone(), self.addresses.sender_address().clone(), self.socket_address, self.mode, @@ -158,7 +158,8 @@ impl Processor for TcpRecvProcessor { #[instrument(skip_all, name = "TcpRecvProcessor::shutdown")] async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.registry.remove_receiver_processor(&ctx.address()); + self.registry + .remove_receiver_processor(ctx.primary_address()); Ok(()) } @@ -174,7 +175,7 @@ impl Processor for TcpRecvProcessor { /// Context to avoid spawning a zombie task. /// 3. We must also stop the TcpReceive loop when the worker gets /// killed by the user or node. - #[instrument(skip_all, name = "TcpRecvProcessor::process", fields(worker = %ctx.address()))] + #[instrument(skip_all, name = "TcpRecvProcessor::process", fields(worker = %ctx.primary_address()))] async fn process(&mut self, ctx: &mut Context) -> Result { // Read the message length let len = match self.read_half.read_u32().await { @@ -242,7 +243,8 @@ impl Processor for TcpRecvProcessor { // Insert the peer address into the return route so that // reply routing can be properly resolved - let local_message = local_message.push_front_return_route(self.addresses.sender_address()); + let local_message = + local_message.push_front_return_route(self.addresses.sender_address().clone()); trace!("Message onward route: {}", local_message.onward_route()); trace!("Message return route: {}", local_message.return_route()); diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/workers/sender.rs b/implementations/rust/ockam/ockam_transport_tcp/src/workers/sender.rs index 9f5cbb0e9a1..cb9fd5c9c1d 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/workers/sender.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/workers/sender.rs @@ -4,10 +4,10 @@ use ockam_core::flow_control::FlowControlId; use ockam_core::{ async_trait, compat::{net::SocketAddr, sync::Arc}, - AllowAll, AllowSourceAddress, DenyAll, LocalMessage, + AddressMetadata, AllowAll, AllowSourceAddress, DenyAll, LocalMessage, }; use ockam_core::{Any, Decodable, Mailbox, Mailboxes, Message, Result, Routed, Worker}; -use ockam_node::{Context, WorkerBuilder}; +use ockam_node::{Context, WorkerBuilder, WorkerShutdownPriority}; use crate::transport_message::TcpTransportMessage; use ockam_transport_core::TransportError; @@ -68,7 +68,7 @@ impl TcpSendWorker { /// manages the connection with the given peer #[allow(clippy::too_many_arguments)] #[instrument(skip_all, name = "TcpSendWorker::start")] - pub(crate) async fn start( + pub(crate) fn start( ctx: &Context, registry: TcpRegistry, write_half: OwnedWriteHalf, @@ -89,12 +89,17 @@ impl TcpSendWorker { let main_mailbox = Mailbox::new( addresses.sender_address().clone(), + Some(AddressMetadata { + is_terminal: true, + attributes: vec![], + }), Arc::new(AllowAll), Arc::new(DenyAll), ); let internal_mailbox = Mailbox::new( addresses.sender_internal_address().clone(), + None, Arc::new(AllowSourceAddress( addresses.receiver_internal_address().clone(), )), @@ -103,19 +108,15 @@ impl TcpSendWorker { WorkerBuilder::new(sender_worker) .with_mailboxes(Mailboxes::new(main_mailbox.clone(), vec![internal_mailbox])) - .terminal(addresses.sender_address().clone()) - .start(ctx) - .await?; + .with_shutdown_priority(WorkerShutdownPriority::Priority1) + .start(ctx)?; Ok(()) } #[instrument(skip_all, name = "TcpSendWorker::stop")] - async fn stop(&self, ctx: &Context) -> Result<()> { - ctx.stop_worker(self.addresses.sender_address().clone()) - .await?; - - Ok(()) + fn stop(&self, ctx: &Context) -> Result<()> { + ctx.stop_address(self.addresses.sender_address()) } fn serialize_message(&mut self, local_message: LocalMessage) -> Result<()> { @@ -166,8 +167,6 @@ impl Worker for TcpSendWorker { #[instrument(skip_all, name = "TcpSendWorker::initialize")] async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await?; - self.registry.add_sender_worker(TcpSenderInfo::new( self.addresses.sender_address().clone(), self.addresses.receiver_address().clone(), @@ -187,7 +186,7 @@ impl Worker for TcpSendWorker { "Failed to send protocol version to peer {}", self.socket_address ); - self.stop(ctx).await?; + self.stop(ctx)?; return Ok(()); } @@ -201,9 +200,7 @@ impl Worker for TcpSendWorker { .remove_sender_worker(self.addresses.sender_address()); if self.rx_should_be_stopped { - let _ = ctx - .stop_processor(self.addresses.receiver_address().clone()) - .await; + let _ = ctx.stop_address(self.addresses.receiver_address()); } Ok(()) @@ -211,7 +208,7 @@ impl Worker for TcpSendWorker { // TcpSendWorker will receive messages from the TcpRouter to send // across the TcpStream to our friend - #[instrument(skip_all, name = "TcpSendWorker::handle_message", fields(worker = %ctx.address()))] + #[instrument(skip_all, name = "TcpSendWorker::handle_message", fields(worker = %ctx.primary_address()))] async fn handle_message( &mut self, ctx: &mut Context, @@ -230,7 +227,7 @@ impl Worker for TcpSendWorker { // No need to stop Receiver as it notified us about connection drop and will // stop itself self.rx_should_be_stopped = false; - self.stop(ctx).await?; + self.stop(ctx)?; return Ok(()); } @@ -243,14 +240,14 @@ impl Worker for TcpSendWorker { if let Err(err) = self.serialize_message(local_message) { // Close the stream - self.stop(ctx).await?; + self.stop(ctx)?; return Err(err); }; if self.write_half.write_all(&self.buffer).await.is_err() { warn!("Failed to send message to peer {}", self.socket_address); - self.stop(ctx).await?; + self.stop(ctx)?; return Ok(()); } diff --git a/implementations/rust/ockam/ockam_transport_tcp/tests/ebpf_portal.rs b/implementations/rust/ockam/ockam_transport_tcp/tests/ebpf_portal.rs index 3a888c3408c..257d95abecc 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/tests/ebpf_portal.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/tests/ebpf_portal.rs @@ -57,7 +57,7 @@ mod tests { #[ockam_macros::test(timeout = 5000)] #[ignore] // Requires root and capabilities async fn privileged_portal__standard_flow__should_succeed(ctx: &mut Context) -> Result<()> { - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let payload1 = generate_binary(); let payload2 = generate_binary(); diff --git a/implementations/rust/ockam/ockam_transport_tcp/tests/interceptor.rs b/implementations/rust/ockam/ockam_transport_tcp/tests/interceptor.rs index 83abdddf974..e23eb0cc124 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/tests/interceptor.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/tests/interceptor.rs @@ -46,7 +46,7 @@ impl PortalInterceptorFactory for MockPortalInterceptorFactory { async fn setup( context: &mut Context, ) -> ockam_core::Result<(String, TcpListener, Arc)> { - let tcp = TcpTransport::create(context).await?; + let tcp = TcpTransport::create(context)?; let listener = { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); @@ -55,8 +55,7 @@ async fn setup( "outlet", bind_address.try_into().unwrap(), TcpOutletOptions::new(), - ) - .await?; + )?; listener }; @@ -71,7 +70,6 @@ async fn setup( Arc::new(AllowAll), Arc::new(AllowAll), ) - .await .unwrap(); let inlet = tcp diff --git a/implementations/rust/ockam/ockam_transport_tcp/tests/keepalive.rs b/implementations/rust/ockam/ockam_transport_tcp/tests/keepalive.rs index 21a57047544..e2003b14c7d 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/tests/keepalive.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/tests/keepalive.rs @@ -8,7 +8,7 @@ use tracing::info; #[ignore] #[ockam_macros::test(timeout = 400000)] async fn tcp_keepalive_test(ctx: &mut Context) -> Result<()> { - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let message: String = rand::thread_rng() .sample_iter(&rand::distributions::Alphanumeric) @@ -42,7 +42,7 @@ async fn tcp_keepalive_test(ctx: &mut Context) -> Result<()> { sleep_duration, reply ); - if let Err(e) = ctx.stop().await { + if let Err(e) = ctx.shutdown_node().await { println!("Unclean stop: {}", e) } diff --git a/implementations/rust/ockam/ockam_transport_tcp/tests/lifecycle.rs b/implementations/rust/ockam/ockam_transport_tcp/tests/lifecycle.rs index 93d6d2da98b..fffb66d6110 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/tests/lifecycle.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/tests/lifecycle.rs @@ -10,10 +10,10 @@ use ockam_transport_tcp::{TcpConnectionOptions, TcpListenerOptions, TcpTransport async fn tcp_lifecycle__two_connections__should_both_work(ctx: &mut Context) -> Result<()> { let options = TcpListenerOptions::new(); ctx.flow_controls() - .add_consumer("echoer", &options.spawner_flow_control_id()); - ctx.start_worker("echoer", Echoer).await?; + .add_consumer(&"echoer".into(), &options.spawner_flow_control_id()); + ctx.start_worker("echoer", Echoer)?; - let transport = TcpTransport::create(ctx).await?; + let transport = TcpTransport::create(ctx)?; let listener = transport.listen("127.0.0.1:0", options).await?; let msg1: String = rand::thread_rng() @@ -52,10 +52,10 @@ async fn tcp_lifecycle__two_connections__should_both_work(ctx: &mut Context) -> async fn tcp_lifecycle__disconnect__should_stop_worker(ctx: &mut Context) -> Result<()> { let options = TcpListenerOptions::new(); ctx.flow_controls() - .add_consumer("echoer", &options.spawner_flow_control_id()); - ctx.start_worker("echoer", Echoer).await?; + .add_consumer(&"echoer".into(), &options.spawner_flow_control_id()); + ctx.start_worker("echoer", Echoer)?; - let transport = TcpTransport::create(ctx).await?; + let transport = TcpTransport::create(ctx)?; let listener = transport.listen("127.0.0.1:0", options).await?; let msg1: String = rand::thread_rng() @@ -91,7 +91,7 @@ async fn tcp_lifecycle__disconnect__should_stop_worker(ctx: &mut Context) -> Res .await?; assert_eq!(reply2, msg2, "Should receive the same message"); - transport.disconnect(connection1.clone()).await?; + transport.disconnect(&connection1)?; let res = ctx .send(route![connection1.clone(), "echoer"], msg1.clone()) .await; @@ -102,7 +102,7 @@ async fn tcp_lifecycle__disconnect__should_stop_worker(ctx: &mut Context) -> Res .await?; assert_eq!(reply3, msg3, "Should receive the same message"); - transport.disconnect(connection2.clone()).await?; + transport.disconnect(&connection2)?; let res = ctx .send(route![connection2.clone(), "echoer"], msg3.clone()) .await; @@ -117,11 +117,11 @@ async fn tcp_lifecycle__stop_listener__should_stop_accepting_connections( ) -> Result<()> { let options = TcpListenerOptions::new(); ctx.flow_controls() - .add_consumer("echoer", &options.spawner_flow_control_id()); + .add_consumer(&"echoer".into(), &options.spawner_flow_control_id()); - ctx.start_worker("echoer", Echoer).await?; + ctx.start_worker("echoer", Echoer)?; - let transport = TcpTransport::create(ctx).await?; + let transport = TcpTransport::create(ctx)?; let listener = transport.listen("127.0.0.1:0", options).await?; let msg1: String = rand::thread_rng() @@ -144,9 +144,7 @@ async fn tcp_lifecycle__stop_listener__should_stop_accepting_connections( .await?; assert_eq!(reply1, msg1, "Should receive the same message"); - transport - .stop_listener(listener.processor_address()) - .await?; + transport.stop_listener(listener.processor_address())?; ctx.sleep(Duration::from_millis(10)).await; let res = transport diff --git a/implementations/rust/ockam/ockam_transport_tcp/tests/portal.rs b/implementations/rust/ockam/ockam_transport_tcp/tests/portal.rs index 30f509eaf01..778143b5f30 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/tests/portal.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/tests/portal.rs @@ -13,7 +13,7 @@ use ockam_transport_tcp::{ const LENGTH: usize = 32; async fn setup(ctx: &Context) -> Result<(String, TcpListener)> { - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let listener = { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); @@ -22,8 +22,7 @@ async fn setup(ctx: &Context) -> Result<(String, TcpListener)> { "outlet", bind_address.try_into().unwrap(), TcpOutletOptions::new(), - ) - .await?; + )?; listener }; @@ -125,7 +124,7 @@ async fn portal__tcp_connection__should_succeed(ctx: &mut Context) -> Result<()> let options = TcpListenerOptions::new(); let outlet_flow_control_id = options.spawner_flow_control_id(); - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let listener = tcp.listen("127.0.0.1:0", options).await?; @@ -142,8 +141,7 @@ async fn portal__tcp_connection__should_succeed(ctx: &mut Context) -> Result<()> "outlet", bind_address.try_into().unwrap(), TcpOutletOptions::new().as_consumer(&outlet_flow_control_id), - ) - .await?; + )?; let inlet = tcp .create_inlet( @@ -182,7 +180,7 @@ async fn portal__tcp_connection_with_invalid_message_flow__should_not_succeed( let options = TcpListenerOptions::new(); - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let tcp_listener = tcp.listen("127.0.0.1:0", options).await?; @@ -197,8 +195,7 @@ async fn portal__tcp_connection_with_invalid_message_flow__should_not_succeed( "outlet_invalid", bind_address.try_into().unwrap(), TcpOutletOptions::new(), - ) - .await?; + )?; let inlet = tcp .create_inlet( @@ -226,7 +223,7 @@ async fn portal__tcp_connection_with_invalid_message_flow__should_not_succeed( handle.abort(); - if let Err(e) = ctx.stop().await { + if let Err(e) = ctx.shutdown_node().await { println!("Unclean stop: {}", e) } @@ -239,7 +236,7 @@ async fn portal__update_route__should_succeed(ctx: &mut Context) -> Result<()> { let payload1 = generate_binary(); let payload2 = generate_binary(); - let tcp = TcpTransport::create(ctx).await?; + let tcp = TcpTransport::create(ctx)?; let listener_outlet = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener_node = tcp.listen("127.0.0.1:0", TcpListenerOptions::new()).await?; @@ -252,8 +249,7 @@ async fn portal__update_route__should_succeed(ctx: &mut Context) -> Result<()> { .to_string() .try_into()?, TcpOutletOptions::new().as_consumer(listener_node.flow_control_id()), - ) - .await?; + )?; let node_connection1 = tcp .connect( @@ -298,11 +294,9 @@ async fn portal__update_route__should_succeed(ctx: &mut Context) -> Result<()> { write_binary(&mut stream, payload1).await; read_assert_binary(&mut stream, payload2).await; - node_connection1.stop(ctx).await?; + node_connection1.stop(ctx)?; - inlet - .update_outlet_node_route(ctx, route![node_connection2]) - .await?; + inlet.update_outlet_node_route(ctx, route![node_connection2])?; let mut stream = TcpStream::connect(inlet.socket_address()).await.unwrap(); write_binary(&mut stream, payload1).await; diff --git a/implementations/rust/ockam/ockam_transport_tcp/tests/send_receive.rs b/implementations/rust/ockam/ockam_transport_tcp/tests/send_receive.rs index 3527133baa9..8865d0613ee 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/tests/send_receive.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/tests/send_receive.rs @@ -8,10 +8,10 @@ use ockam_transport_tcp::{TcpConnectionOptions, TcpListenerOptions, TcpTransport async fn send_receive(ctx: &mut Context) -> Result<()> { let options = TcpListenerOptions::new(); ctx.flow_controls() - .add_consumer("echoer", &options.spawner_flow_control_id()); - ctx.start_worker("echoer", Echoer).await?; + .add_consumer(&"echoer".into(), &options.spawner_flow_control_id()); + ctx.start_worker("echoer", Echoer)?; - let transport = TcpTransport::create(ctx).await?; + let transport = TcpTransport::create(ctx)?; let listener = transport.listen("127.0.0.1:0", options).await?; let addr = transport diff --git a/implementations/rust/ockam/ockam_transport_udp/src/lib.rs b/implementations/rust/ockam/ockam_transport_udp/src/lib.rs index 70bfe40b390..023cfd7b551 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/lib.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/lib.rs @@ -27,8 +27,6 @@ pub use options::UdpBindOptions; pub use puncture::*; pub use transport::{UdpBind, UdpBindArguments, UdpTransport, UdpTransportExtension}; -pub(crate) const CLUSTER_NAME: &str = "_internals.transport.udp"; - /// Transport type for UDP addresses pub const UDP: ockam_core::TransportType = ockam_core::TransportType::new(2); diff --git a/implementations/rust/ockam/ockam_transport_udp/src/options.rs b/implementations/rust/ockam/ockam_transport_udp/src/options.rs index 50d641246fc..8e18009a0e2 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/options.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/options.rs @@ -36,14 +36,14 @@ impl UdpBindOptions { impl UdpBindOptions { pub(crate) fn setup_flow_control(&self, flow_controls: &FlowControls, addresses: &Addresses) { flow_controls.add_producer( - addresses.receiver_address().clone(), + addresses.receiver_address(), &self.flow_control_id, None, vec![addresses.sender_address().clone()], ); for id in &self.consumer { - flow_controls.add_consumer(addresses.sender_address().clone(), id); + flow_controls.add_consumer(addresses.sender_address(), id); } } diff --git a/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/listener.rs b/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/listener.rs index 84791d2cb8d..bc572bdbe96 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/listener.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/listener.rs @@ -5,9 +5,7 @@ use crate::puncture::negotiation::options::UdpPunctureNegotiationListenerOptions use crate::puncture::rendezvous_service::RendezvousClient; use crate::{UdpBindArguments, UdpBindOptions, UdpPuncture, UdpPunctureOptions, UdpTransport}; use ockam_core::flow_control::FlowControlId; -use ockam_core::{ - async_trait, Address, AllowAll, AsyncTryClone, DenyAll, Result, Route, Routed, Worker, -}; +use ockam_core::{async_trait, Address, AllowAll, DenyAll, Result, Route, Routed, Worker}; use ockam_node::{Context, WorkerBuilder}; use tracing::{error, info}; @@ -20,7 +18,7 @@ pub struct UdpPunctureNegotiationListener { impl UdpPunctureNegotiationListener { /// Create and start a new listener on given address - pub async fn create( + pub fn create( ctx: &Context, address: impl Into
, udp: &UdpTransport, @@ -43,8 +41,7 @@ impl UdpPunctureNegotiationListener { .with_address(address) .with_incoming_access_control_arc(access_control) .with_outgoing_access_control(DenyAll) - .start(ctx) - .await?; + .start(ctx)?; Ok(()) } @@ -75,7 +72,7 @@ impl UdpPunctureNegotiationListener { "Error getting UDP public address for the responder: {}", err ); - udp.unbind(udp_bind.sender_address().clone()).await?; + udp.unbind(udp_bind.sender_address())?; return Err(err); } }; @@ -103,8 +100,7 @@ impl UdpPunctureNegotiationListener { // that `UdpPunctureReceiverWorker` was started on the other side, we'll start // sending messages to that worker true, - ) - .await?; + )?; // Send Acknowledge back, so that initiator will start the puncture as well ctx.send( @@ -135,16 +131,14 @@ impl Worker for UdpPunctureNegotiationListener { let return_route = msg.return_route().clone(); let msg = msg.into_body()?; - let child_ctx = ctx - .new_detached( - Address::random_tagged("UdpPunctureNegotiator.responder"), - DenyAll, - AllowAll, - ) - .await?; + let child_ctx = ctx.new_detached( + Address::random_tagged("UdpPunctureNegotiator.responder"), + DenyAll, + AllowAll, + )?; let rendezvous_route = self.rendezvous_route.clone(); - let udp = self.udp.async_try_clone().await?; + let udp = self.udp.clone(); let flow_control_id = self.flow_control_id.clone(); tokio::spawn(async move { Self::start_puncture( diff --git a/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/negotiation.rs b/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/negotiation.rs index 331b9c41761..3c57b61e5a1 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/negotiation.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/negotiation.rs @@ -25,7 +25,7 @@ impl UdpPunctureNegotiation { let next = onward_route.next()?.clone(); let address = Address::random_tagged("UdpPunctureNegotiator.initiator"); - let mut child_ctx = ctx.new_detached(address, AllowAll, AllowAll).await?; + let mut child_ctx = ctx.new_detached(address, AllowAll, AllowAll)?; if let Some(flow_control_id) = ctx .flow_controls() @@ -34,7 +34,7 @@ impl UdpPunctureNegotiation { { // To be able to receive the response ctx.flow_controls() - .add_consumer(child_ctx.address(), &flow_control_id); + .add_consumer(child_ctx.primary_address(), &flow_control_id); } // We create a new bind for each puncture. Ownership will be transferred to the @@ -49,7 +49,7 @@ impl UdpPunctureNegotiation { debug!( "Initializing UdpPunctureNegotiation Initiator at {}", - child_ctx.address_ref() + child_ctx.primary_address() ); let client = RendezvousClient::new(&udp_bind, rendezvous_route); let my_udp_public_address = match client.get_my_address(ctx).await { @@ -59,14 +59,14 @@ impl UdpPunctureNegotiation { "Error getting UDP public address for the initiator: {}", err ); - udp.unbind(udp_bind.sender_address().clone()).await?; + udp.unbind(udp_bind.sender_address())?; return Err(err); } }; info!( "UdpPunctureNegotiation Initiator {} got its public address: {}", - child_ctx.address_ref(), + child_ctx.primary_address(), my_udp_public_address ); @@ -94,11 +94,11 @@ impl UdpPunctureNegotiation { Err(err) => { error!( "Error receiving response for Udp Puncture at: {}. {}", - child_ctx.address_ref(), + child_ctx.primary_address(), err ); - udp.unbind(udp_bind.sender_address().clone()).await?; + udp.unbind(udp_bind.sender_address())?; return Err(err); } }; @@ -108,11 +108,11 @@ impl UdpPunctureNegotiation { Err(err) => { error!( "Invalid response for Udp Puncture at: {}. {}", - child_ctx.address_ref(), + child_ctx.primary_address(), err ); - udp.unbind(udp_bind.sender_address().clone()).await?; + udp.unbind(udp_bind.sender_address())?; return Err(err); } }; @@ -128,8 +128,7 @@ impl UdpPunctureNegotiation { Address::from(response.responder_remote_address), options, false, - ) - .await?; + )?; Ok(puncture) } diff --git a/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/options.rs b/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/options.rs index 909869146ce..2870694e0bd 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/options.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/puncture/negotiation/options.rs @@ -74,10 +74,10 @@ impl UdpPunctureNegotiationListenerOptions { address: &Address, ) { for id in &self.consumer { - flow_controls.add_consumer(address.clone(), id); + flow_controls.add_consumer(address, id); } - flow_controls.add_spawner(address.clone(), &self.flow_control_id); + flow_controls.add_spawner(address, &self.flow_control_id); } /// Spawner [`FlowControlId`] diff --git a/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/options.rs b/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/options.rs index 0b43623c12c..e0aad4ebbcf 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/options.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/options.rs @@ -56,11 +56,11 @@ impl UdpPunctureOptions { .map(|x| x.flow_control_id().clone()) { // Allow a sender with corresponding flow_control_id send messages to this address - flow_controls.add_consumer(addresses.remote_address().clone(), &flow_control_id); + flow_controls.add_consumer(addresses.remote_address(), &flow_control_id); } flow_controls.add_producer( - addresses.receiver_address().clone(), + addresses.receiver_address(), &self.flow_control_id, None, vec![addresses.sender_address().clone()], diff --git a/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/puncture.rs b/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/puncture.rs index f0262092d95..b5d4d64dd44 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/puncture.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/puncture.rs @@ -24,7 +24,7 @@ pub struct UdpPuncture { // TODO: PUNCTURE make keepalives adjustable impl UdpPuncture { - pub(crate) async fn create( + pub(crate) fn create( ctx: &Context, bind: UdpBind, peer_udp_address: String, @@ -50,8 +50,7 @@ impl UdpPuncture { notify_puncture_open_sender, options, redirect_first_message_to_transport, - ) - .await?; + )?; Ok(UdpPuncture { notify_puncture_open_receiver, @@ -76,9 +75,8 @@ impl UdpPuncture { } /// Stop the receiver (which will shut down everything else as well) - pub async fn stop(&self, ctx: &Context) -> Result<()> { - ctx.stop_worker(self.addresses.receiver_address().clone()) - .await + pub fn stop(&self, ctx: &Context) -> Result<()> { + ctx.stop_address(self.addresses.receiver_address()) } /// Flow Control Id diff --git a/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/receiver.rs b/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/receiver.rs index a49cd0bf8ac..8b36c205cc4 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/receiver.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/puncture/puncture/receiver.rs @@ -54,7 +54,7 @@ pub(crate) struct UdpPunctureReceiverWorker { impl UdpPunctureReceiverWorker { #[allow(clippy::too_many_arguments)] - pub(crate) async fn create( + pub(crate) fn create( ctx: &Context, bind: UdpBind, peer_udp_address: String, @@ -64,11 +64,11 @@ impl UdpPunctureReceiverWorker { options: UdpPunctureOptions, redirect_first_message_to_transport: bool, ) -> Result<()> { - let heartbeat = - DelayedEvent::create(ctx, addresses.heartbeat_address().clone(), ()).await?; + let heartbeat = DelayedEvent::create(ctx, addresses.heartbeat_address().clone(), ())?; let remote_mailbox = Mailbox::new( addresses.remote_address().clone(), + None, Arc::new(AllowAll), Arc::new(AllowAll), ); @@ -77,13 +77,15 @@ impl UdpPunctureReceiverWorker { let receiver_mailbox = Mailbox::new( addresses.receiver_address().clone(), + None, Arc::new(DenyAll), options.create_receiver_outgoing_access_control(ctx.flow_controls()), ); let heartbeat_mailbox = Mailbox::new( addresses.heartbeat_address().clone(), - Arc::new(AllowSourceAddress(heartbeat.address())), + None, + Arc::new(AllowSourceAddress(heartbeat.address().clone())), Arc::new(DenyAll), ); @@ -93,8 +95,7 @@ impl UdpPunctureReceiverWorker { .with_address(addresses.sender_address().clone()) .with_incoming_access_control(AllowAll) .with_outgoing_access_control(AllowAll) - .start(ctx) - .await?; + .start(ctx)?; // Create and start worker let receiver_worker = Self { @@ -115,8 +116,7 @@ impl UdpPunctureReceiverWorker { remote_mailbox, vec![receiver_mailbox, heartbeat_mailbox], )) - .start(ctx) - .await?; + .start(ctx)?; Ok(()) } @@ -179,10 +179,7 @@ impl UdpPunctureReceiverWorker { } => { trace!("Received Payload from peer. Will forward to local entity"); - let return_route = return_route - .modify() - .prepend(self.addresses.sender_address().clone()) - .into(); + let return_route = self.addresses.sender_address().clone() + return_route; // Update routing & payload let local_message = LocalMessage::new() @@ -216,8 +213,7 @@ impl UdpPunctureReceiverWorker { .send(UdpPunctureNotification::Closed); // Shut down itself - ctx.stop_worker(self.addresses.remote_address().clone()) - .await?; + ctx.stop_address(self.addresses.remote_address())?; return Ok(()); } @@ -256,7 +252,7 @@ impl UdpPunctureReceiverWorker { let res = self.handle_heartbeat_impl(ctx).await; // Schedule next heartbeat here in case something errors - self.heartbeat.schedule(HEARTBEAT_INTERVAL).await?; + self.heartbeat.schedule(HEARTBEAT_INTERVAL)?; res } @@ -268,19 +264,15 @@ impl Worker for UdpPunctureReceiverWorker { type Context = Context; async fn initialize(&mut self, _context: &mut Self::Context) -> Result<()> { - self.heartbeat.schedule(Duration::ZERO).await?; - - Ok(()) + self.heartbeat.schedule(Duration::ZERO) } async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { self.heartbeat.cancel(); - _ = ctx - .stop_worker(self.addresses.sender_address().clone()) - .await; + _ = ctx.stop_address(self.addresses.sender_address()); - _ = ctx.stop_worker(self.bind.sender_address().clone()).await; + _ = ctx.stop_address(self.bind.sender_address()); Ok(()) } diff --git a/implementations/rust/ockam/ockam_transport_udp/src/puncture/rendezvous_service/client.rs b/implementations/rust/ockam/ockam_transport_udp/src/puncture/rendezvous_service/client.rs index b4b1ad609ee..2f0ad53b69f 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/puncture/rendezvous_service/client.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/puncture/rendezvous_service/client.rs @@ -1,7 +1,6 @@ use crate::puncture::rendezvous_service::{RendezvousRequest, RendezvousResponse}; use crate::{PunctureError, UdpBind}; -use ockam_core::AsyncTryClone; -use ockam_core::{route, Result, Route}; +use ockam_core::{Result, Route}; use ockam_node::{Context, MessageSendReceiveOptions}; use std::time::Duration; @@ -10,8 +9,6 @@ use std::time::Duration; const QUICK_TIMEOUT: Duration = Duration::from_secs(3); /// Client to the Rendezvous server -#[derive(AsyncTryClone)] -#[async_try_clone(crate = "ockam_core")] pub struct RendezvousClient { rendezvous_route: Route, } @@ -19,7 +16,7 @@ pub struct RendezvousClient { impl RendezvousClient { /// Constructor pub fn new(udp_bind: &UdpBind, rendezvous_route: Route) -> Self { - let full_route = route![udp_bind.sender_address().clone(), rendezvous_route]; + let full_route = udp_bind.sender_address().clone() + rendezvous_route; Self { rendezvous_route: full_route, diff --git a/implementations/rust/ockam/ockam_transport_udp/src/puncture/rendezvous_service/rendezvous.rs b/implementations/rust/ockam/ockam_transport_udp/src/puncture/rendezvous_service/rendezvous.rs index 403cb4a2038..dd81c6c2f8c 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/puncture/rendezvous_service/rendezvous.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/puncture/rendezvous_service/rendezvous.rs @@ -19,19 +19,18 @@ use tracing::{debug, info, warn}; /// # async fn test(ctx: Context) -> Result<()> { /// /// // Start a Rendezvous service with address 'rendezvous' and listen on UDP port 4000 -/// RendezvousService::start(&ctx, "rendezvous").await?; -/// let udp = UdpTransport::create(&ctx).await?; +/// RendezvousService::start(&ctx, "rendezvous")?; +/// let udp = UdpTransport::create(&ctx)?; /// let bind = udp.bind(UdpBindArguments::new().with_bind_address("0.0.0.0:4000")?, UdpBindOptions::new()).await?; -/// ctx.flow_controls().add_consumer("rendezvous", bind.flow_control_id()); +/// ctx.flow_controls().add_consumer(&"rendezvous".into(), bind.flow_control_id()); /// # Ok(()) } /// ``` pub struct RendezvousService; impl RendezvousService { /// Start a new Rendezvous service with the given local address - pub async fn start(ctx: &Context, address: impl Into
) -> Result<()> { + pub fn start(ctx: &Context, address: impl Into
) -> Result<()> { ctx.start_worker(address.into(), RendezvousServiceWorker::new()) - .await } } @@ -182,15 +181,15 @@ mod tests { /// Helper async fn test_setup(ctx: &mut Context) -> Result<(Route, UdpBind)> { // Create transport, start rendezvous service, start echo service and listen - let transport = UdpTransport::create(ctx).await?; - RendezvousService::start(ctx, "rendezvous").await?; + let transport = UdpTransport::create(ctx)?; + RendezvousService::start(ctx, "rendezvous")?; let udp_bind = transport .bind(UdpBindArguments::new(), UdpBindOptions::new()) .await?; ctx.flow_controls() - .add_consumer("rendezvous", udp_bind.flow_control_id()); + .add_consumer(&"rendezvous".into(), udp_bind.flow_control_id()); let bind_addr = udp_bind.bind_address().to_string(); @@ -201,7 +200,7 @@ mod tests { ]; ctx.flow_controls() - .add_consumer("echo", udp_bind.flow_control_id()); + .add_consumer(&"echo".into(), udp_bind.flow_control_id()); Ok((rendezvous_route, udp_bind)) } diff --git a/implementations/rust/ockam/ockam_transport_udp/src/transport/bind.rs b/implementations/rust/ockam/ockam_transport_udp/src/transport/bind.rs index 74cb2bd14f7..99338a93dfd 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/transport/bind.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/transport/bind.rs @@ -6,7 +6,7 @@ use ockam_core::errcode::{Kind, Origin}; use ockam_core::flow_control::FlowControlId; use ockam_core::{Address, AllowAll, DenyAll, Error, Result}; use ockam_node::compat::asynchronous::resolve_peer; -use ockam_node::{ProcessorBuilder, WorkerBuilder}; +use ockam_node::{ProcessorBuilder, WorkerBuilder, WorkerShutdownPriority}; use ockam_transport_core::{parse_socket_addr, TransportError}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use tokio::net::UdpSocket; @@ -119,8 +119,7 @@ impl UdpTransport { .with_address(addresses.sender_address().clone()) .with_incoming_access_control(AllowAll) .with_outgoing_access_control(DenyAll) - .start(&self.ctx) - .await?; + .start(&self.ctx)?; let receiver = UdpReceiverProcessor::new(addresses.clone(), socket_read, arguments.peer_address); @@ -128,8 +127,8 @@ impl UdpTransport { .with_address(addresses.receiver_address().clone()) .with_incoming_access_control(DenyAll) .with_outgoing_access_control_arc(receiver_outgoing_access_control) - .start(&self.ctx) - .await?; + .with_shutdown_priority(WorkerShutdownPriority::Priority1) + .start(&self.ctx)?; let bind = UdpBind::new( addresses, @@ -142,8 +141,8 @@ impl UdpTransport { } /// Interrupt an active TCP connection given its Sender `Address` - pub async fn unbind(&self, address: impl Into
) -> Result<()> { - self.ctx.stop_worker(address.into()).await + pub fn unbind(&self, address: &Address) -> Result<()> { + self.ctx.stop_address(address) } } @@ -217,3 +216,9 @@ impl From for Address { value.addresses.sender_address().clone() } } + +impl AsRef
for UdpBind { + fn as_ref(&self) -> &Address { + self.addresses.sender_address() + } +} diff --git a/implementations/rust/ockam/ockam_transport_udp/src/transport/lifecycle.rs b/implementations/rust/ockam/ockam_transport_udp/src/transport/lifecycle.rs index ae94e0d3e91..42f60c89968 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/transport/lifecycle.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/transport/lifecycle.rs @@ -1,5 +1,5 @@ use ockam_core::errcode::{Kind, Origin}; -use ockam_core::{async_trait, Address, AsyncTryClone, Error, Result, TransportType}; +use ockam_core::{async_trait, Address, Error, Result, TransportType, TryClone}; use ockam_node::Context; use ockam_transport_core::Transport; use std::sync::Arc; @@ -16,13 +16,13 @@ impl UdpTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let udp = UdpTransport::create(&ctx).await?; + /// let udp = UdpTransport::create(&ctx)?; /// # Ok(()) } /// ``` #[instrument(name = "create udp transport", skip_all)] - pub async fn create(ctx: &Context) -> Result { + pub fn create(ctx: &Context) -> Result { let udp = Self { - ctx: Arc::new(ctx.async_try_clone().await?), + ctx: Arc::new(ctx.try_clone()?), }; // make the UDP transport available in the list of supported transports for // later address resolution when socket addresses will need to be instantiated as UDP @@ -45,7 +45,7 @@ impl Transport for UdpTransport { UDP } - async fn resolve_address(&self, address: Address) -> Result
{ + async fn resolve_address(&self, address: &Address) -> Result
{ if address.transport_type() == UDP { Ok(self .bind( @@ -68,8 +68,8 @@ impl Transport for UdpTransport { } } - async fn disconnect(&self, address: Address) -> Result<()> { - self.unbind(address).await + fn disconnect(&self, address: &Address) -> Result<()> { + self.unbind(address) } } @@ -82,20 +82,20 @@ mod tests { #[ockam_macros::test] async fn test_resolve_address(ctx: &mut Context) -> Result<()> { - let udp = UdpTransport::create(ctx).await?; + let udp = UdpTransport::create(ctx)?; let udp_address = "127.0.0.1:0"; - let initial_workers = ctx.list_workers(); + let initial_workers = ctx.list_workers()?; let socket = UdpSocket::bind(udp_address) .await .map_err(TransportError::from)?; let socket_address = socket.local_addr().unwrap().to_string(); let resolved = udp - .resolve_address(Address::new_with_string(UDP, socket_address.clone())) + .resolve_address(&Address::new_with_string(UDP, socket_address.clone())) .await?; // there are 2 additional workers - let mut additional_workers = ctx.list_workers(); + let mut additional_workers = ctx.list_workers()?; additional_workers.retain(|w| !initial_workers.contains(w)); assert_eq!(additional_workers.len(), 2); @@ -104,7 +104,7 @@ mod tests { // trying to resolve the address a second time should still work let _route = udp - .resolve_address(Address::new_with_string(UDP, socket_address)) + .resolve_address(&Address::new_with_string(UDP, socket_address)) .await?; tokio::time::sleep(Duration::from_millis(250)).await; @@ -114,7 +114,7 @@ mod tests { #[ockam_macros::test] async fn test_resolve_route_with_dns_address(ctx: &mut Context) -> Result<()> { - let udp = UdpTransport::create(ctx).await?; + let udp = UdpTransport::create(ctx)?; let udp_address = "127.0.0.1:0"; let socket = UdpSocket::bind(udp_address) .await @@ -122,7 +122,7 @@ mod tests { let socket_address = socket.local_addr().unwrap(); let result = udp - .resolve_address(Address::new_with_string( + .resolve_address(&Address::new_with_string( UDP, format!("localhost:{}", socket_address.port()), )) diff --git a/implementations/rust/ockam/ockam_transport_udp/src/transport/mod.rs b/implementations/rust/ockam/ockam_transport_udp/src/transport/mod.rs index fab60589063..e0974dff7fc 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/transport/mod.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/transport/mod.rs @@ -21,7 +21,7 @@ pub struct UdpTransport { pub trait UdpTransportExtension: HasContext { /// Create a UDP transport async fn create_udp_transport(&self) -> Result { - UdpTransport::create(self.get_context()).await + UdpTransport::create(self.get_context()) } } diff --git a/implementations/rust/ockam/ockam_transport_udp/src/transport/puncture.rs b/implementations/rust/ockam/ockam_transport_udp/src/transport/puncture.rs index 5b1674b1777..2e608e780fd 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/transport/puncture.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/transport/puncture.rs @@ -3,7 +3,7 @@ use ockam_core::{Address, Result}; impl UdpTransport { /// Start a new puncture - pub async fn puncture( + pub fn puncture( &self, bind: UdpBind, peer_udp_address: String, @@ -21,11 +21,10 @@ impl UdpTransport { options, redirect_first_message_to_transport, ) - .await } /// Stop a puncture - pub async fn stop_puncture(&self, puncture: UdpPuncture) -> Result<()> { - puncture.stop(&self.ctx).await + pub fn stop_puncture(&self, puncture: UdpPuncture) -> Result<()> { + puncture.stop(&self.ctx) } } diff --git a/implementations/rust/ockam/ockam_transport_udp/src/workers/receiver.rs b/implementations/rust/ockam/ockam_transport_udp/src/workers/receiver.rs index 490e92e207d..ffe979f1efa 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/workers/receiver.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/workers/receiver.rs @@ -144,10 +144,6 @@ impl UdpReceiverProcessor { impl Processor for UdpReceiverProcessor { type Context = Context; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await - } - async fn process(&mut self, ctx: &mut Self::Context) -> Result { trace!("Waiting for incoming UDP datagram..."); diff --git a/implementations/rust/ockam/ockam_transport_udp/src/workers/sender.rs b/implementations/rust/ockam/ockam_transport_udp/src/workers/sender.rs index ad696e2e5ee..6347d5124cb 100644 --- a/implementations/rust/ockam/ockam_transport_udp/src/workers/sender.rs +++ b/implementations/rust/ockam/ockam_transport_udp/src/workers/sender.rs @@ -47,9 +47,7 @@ impl Worker for UdpSenderWorker { type Context = Context; async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { - let _ = ctx - .stop_processor(self.addresses.receiver_address().clone()) - .await; + let _ = ctx.stop_address(self.addresses.receiver_address()); Ok(()) } @@ -68,7 +66,7 @@ impl Worker for UdpSenderWorker { *peer } else { // Resolve peer address to IPv4 SocketAddr(s). - let peer_addr = msg.next_on_onward_route()?; + let peer_addr = msg.next_on_onward_route()?.clone(); msg = msg.pop_front_onward_route()?; if peer_addr.transport_type() != UDP { diff --git a/implementations/rust/ockam/ockam_transport_udp/tests/tests.rs b/implementations/rust/ockam/ockam_transport_udp/tests/tests.rs index f2c2815edae..48ba6a2cd3a 100644 --- a/implementations/rust/ockam/ockam_transport_udp/tests/tests.rs +++ b/implementations/rust/ockam/ockam_transport_udp/tests/tests.rs @@ -16,16 +16,16 @@ const TIMEOUT: Duration = Duration::from_secs(5); #[ockam_macros::test] async fn reply_from_correct_server_port(ctx: &mut Context) -> Result<()> { // Transport - let transport = UdpTransport::create(ctx).await?; + let transport = UdpTransport::create(ctx)?; // Listener - ctx.start_worker("echoer", Echoer::new(true)).await?; + ctx.start_worker("echoer", Echoer::new(true))?; let bind = transport .bind(UdpBindArguments::new(), UdpBindOptions::new()) .await?; ctx.flow_controls() - .add_consumer("echoer", bind.flow_control_id()); + .add_consumer(&"echoer".into(), bind.flow_control_id()); // Sender { @@ -80,10 +80,10 @@ async fn recover_from_sender_error(ctx: &mut Context) -> Result<()> { debug!("addr_nok = {:?}", addr_nok); // Transport - let transport = UdpTransport::create(ctx).await?; + let transport = UdpTransport::create(ctx)?; // Listener - ctx.start_worker("echoer", Echoer::new(true)).await?; + ctx.start_worker("echoer", Echoer::new(true))?; let bind = transport .bind( UdpBindArguments::new().with_bind_address(addr_ok.clone())?, @@ -91,7 +91,7 @@ async fn recover_from_sender_error(ctx: &mut Context) -> Result<()> { ) .await?; ctx.flow_controls() - .add_consumer("echoer", bind.flow_control_id()); + .add_consumer(&"echoer".into(), bind.flow_control_id()); // Send message to try and cause a socket send error let r = route![bind.sender_address().clone(), (UDP, addr_nok), "echoer"]; @@ -129,11 +129,11 @@ async fn send_from_same_client_port(ctx: &mut Context) -> Result<()> { debug!("bind_addrs = {:?}", bind_addrs); // Transport - let transport = UdpTransport::create(ctx).await?; + let transport = UdpTransport::create(ctx)?; // Listeners // Note: it is the Echoer which is checking the UDP ports for this test - ctx.start_worker("echoer", Echoer::new(true)).await?; + ctx.start_worker("echoer", Echoer::new(true))?; let mut binds = vec![]; for addr in &bind_addrs { let bind = transport @@ -144,7 +144,7 @@ async fn send_from_same_client_port(ctx: &mut Context) -> Result<()> { .await?; ctx.flow_controls() - .add_consumer("echoer", bind.flow_control_id()); + .add_consumer(&"echoer".into(), bind.flow_control_id()); binds.push(bind); } @@ -174,9 +174,9 @@ async fn send_from_same_client_port(ctx: &mut Context) -> Result<()> { #[ockam_macros::test] async fn send_receive_arbitrary_udp_peer(ctx: &mut Context) -> Result<()> { // Transport - let transport = UdpTransport::create(ctx).await?; + let transport = UdpTransport::create(ctx)?; - ctx.start_worker("echoer", Echoer::new(true)).await?; + ctx.start_worker("echoer", Echoer::new(true))?; let bind1 = transport .bind(UdpBindArguments::new(), UdpBindOptions::new()) .await?; @@ -188,9 +188,9 @@ async fn send_receive_arbitrary_udp_peer(ctx: &mut Context) -> Result<()> { .await?; ctx.flow_controls() - .add_consumer("echoer", bind2.flow_control_id()); + .add_consumer(&"echoer".into(), bind2.flow_control_id()); ctx.flow_controls() - .add_consumer("echoer", bind3.flow_control_id()); + .add_consumer(&"echoer".into(), bind3.flow_control_id()); // Sender { @@ -240,9 +240,9 @@ async fn send_receive_arbitrary_udp_peer(ctx: &mut Context) -> Result<()> { #[ockam_macros::test] async fn send_receive_one_known_udp_peer(ctx: &mut Context) -> Result<()> { // Transport - let transport = UdpTransport::create(ctx).await?; + let transport = UdpTransport::create(ctx)?; - ctx.start_worker("echoer", Echoer::new(false)).await?; + ctx.start_worker("echoer", Echoer::new(false))?; let bind1 = transport .bind(UdpBindArguments::new(), UdpBindOptions::new()) .await?; @@ -256,9 +256,9 @@ async fn send_receive_one_known_udp_peer(ctx: &mut Context) -> Result<()> { .await?; ctx.flow_controls() - .add_consumer("echoer", bind1.flow_control_id()); + .add_consumer(&"echoer".into(), bind1.flow_control_id()); ctx.flow_controls() - .add_consumer("echoer", bind2.flow_control_id()); + .add_consumer(&"echoer".into(), bind2.flow_control_id()); // Sender { @@ -308,9 +308,9 @@ async fn send_receive_two_known_udp_peers(ctx: &mut Context) -> Result<()> { debug!("bind_addrs = {:?}", bind_addrs); // Transport - let transport = UdpTransport::create(ctx).await?; + let transport = UdpTransport::create(ctx)?; - ctx.start_worker("echoer", Echoer::new(false)).await?; + ctx.start_worker("echoer", Echoer::new(false))?; let bind1 = transport .bind( UdpBindArguments::new() @@ -331,9 +331,9 @@ async fn send_receive_two_known_udp_peers(ctx: &mut Context) -> Result<()> { .await?; ctx.flow_controls() - .add_consumer("echoer", bind1.flow_control_id()); + .add_consumer(&"echoer".into(), bind1.flow_control_id()); ctx.flow_controls() - .add_consumer("echoer", bind2.flow_control_id()); + .add_consumer(&"echoer".into(), bind2.flow_control_id()); // Sender { @@ -379,9 +379,9 @@ async fn send_receive_large_message(ctx: &mut Context) -> Result<()> { debug!("bind_addrs = {:?}", bind_addrs); // Transport - let transport = UdpTransport::create(ctx).await?; + let transport = UdpTransport::create(ctx)?; - ctx.start_worker("echoer", Echoer::new(false)).await?; + ctx.start_worker("echoer", Echoer::new(false))?; let bind1 = transport .bind( UdpBindArguments::new() @@ -402,7 +402,7 @@ async fn send_receive_large_message(ctx: &mut Context) -> Result<()> { .await?; ctx.flow_controls() - .add_consumer("echoer", bind1.flow_control_id()); + .add_consumer(&"echoer".into(), bind1.flow_control_id()); let msg: String = rand::thread_rng() .sample_iter(&rand::distributions::Alphanumeric) diff --git a/implementations/rust/ockam/ockam_transport_uds/src/router/handle.rs b/implementations/rust/ockam/ockam_transport_uds/src/router/handle.rs index fff7d4a2d35..854f425450c 100644 --- a/implementations/rust/ockam/ockam_transport_uds/src/router/handle.rs +++ b/implementations/rust/ockam/ockam_transport_uds/src/router/handle.rs @@ -1,8 +1,6 @@ use std::os::unix::net::SocketAddr; -use ockam_core::{ - async_trait, compat::sync::Arc, Address, AsyncTryClone, DenyAll, Mailbox, Mailboxes, Result, -}; +use ockam_core::{Address, Result, TryClone}; use ockam_node::Context; use ockam_transport_core::TransportError; @@ -17,33 +15,14 @@ use super::{UdsRouterRequest, UdsRouterResponse}; /// A handle to connect to a [`UdsRouter`](crate::router::UdsRouter) /// /// Dropping this handle is harmless +#[derive(TryClone)] +#[try_clone(crate = "ockam_core")] pub(crate) struct UdsRouterHandle { ctx: Context, main_addr: Address, api_addr: Address, } -#[async_trait] -impl AsyncTryClone for UdsRouterHandle { - async fn async_try_clone(&self) -> Result { - let mailboxes = Mailboxes::new( - Mailbox::new( - Address::random_tagged("UdsRouterHandle.async_try_clone.detached"), - Arc::new(DenyAll), - Arc::new(DenyAll), - ), - vec![], - ); - let child_ctx = self.ctx.new_detached_with_mailboxes(mailboxes).await?; - - Ok(Self::new( - child_ctx, - self.main_addr.clone(), - self.api_addr.clone(), - )) - } -} - impl UdsRouterHandle { /// Create a new [`UdsRouterHandle`] with the given address pub(crate) fn new(ctx: Context, main_addr: Address, api_addr: Address) -> Self { @@ -67,9 +46,9 @@ impl UdsRouterHandle { impl UdsRouterHandle { /// Bind an incoming connection listener for this router - pub async fn bind(&self, addr: impl Into) -> Result { + pub fn bind(&self, addr: impl Into) -> Result { let socket_addr = addr.into(); - UdsListenProcessor::start(&self.ctx, self.async_try_clone().await?, socket_addr).await + UdsListenProcessor::start(&self.ctx, self.try_clone()?, socket_addr) } /// Establish an outgoing UDS connection on an existing transport diff --git a/implementations/rust/ockam/ockam_transport_uds/src/router/uds_router.rs b/implementations/rust/ockam/ockam_transport_uds/src/router/uds_router.rs index af5d98aba75..49bd07dd40f 100644 --- a/implementations/rust/ockam/ockam_transport_uds/src/router/uds_router.rs +++ b/implementations/rust/ockam/ockam_transport_uds/src/router/uds_router.rs @@ -29,14 +29,14 @@ pub(crate) struct UdsRouter { /// Public Implementations to instantiate a UDS Router and UDS Router Handler impl UdsRouter { /// Create and register a new UDS router with the given node context - pub async fn register(ctx: &Context) -> Result { + pub fn register(ctx: &Context) -> Result { // This context is only used to start workers, doesn't need to send nor receive messages let mailboxes = Mailboxes::new( Mailbox::deny_all(Address::random_tagged("UdsRouter.detached")), vec![], ); - let child_ctx = ctx.new_detached_with_mailboxes(mailboxes).await?; + let child_ctx = ctx.new_detached_with_mailboxes(mailboxes)?; let main_addr = Address::random_tagged("UdsRouter_main_addr"); let api_addr = Address::random_tagged("UdsRouter_api_addr"); @@ -50,14 +50,23 @@ impl UdsRouter { allow_auto_connection: true, }; - let handle = router.create_self_handle().await?; - let main_mailbox = Mailbox::new(main_addr.clone(), Arc::new(AllowAll), Arc::new(AllowAll)); - let api_mailbox = Mailbox::new(api_addr.clone(), Arc::new(AllowAll), Arc::new(AllowAll)); + let handle = router.create_self_handle()?; + let main_mailbox = Mailbox::new( + main_addr.clone(), + None, + Arc::new(AllowAll), + Arc::new(AllowAll), + ); + let api_mailbox = Mailbox::new( + api_addr.clone(), + None, + Arc::new(AllowAll), + Arc::new(AllowAll), + ); WorkerBuilder::new(router) .with_mailboxes(Mailboxes::new(main_mailbox, vec![api_mailbox])) - .start(ctx) - .await?; + .start(ctx)?; trace!("Registering UDS router for type = {}", UDS); ctx.register(UDS, main_addr)?; @@ -66,13 +75,13 @@ impl UdsRouter { } /// Create a new [`UdsRouterHandle`] representing this router - pub async fn create_self_handle(&self) -> Result { + pub fn create_self_handle(&self) -> Result { let mailboxes = Mailboxes::new( Mailbox::deny_all(Address::random_tagged("UdsRouterHandle.detached")), vec![], ); - let handle_ctx = self.ctx.new_detached_with_mailboxes(mailboxes).await?; + let handle_ctx = self.ctx.new_detached_with_mailboxes(mailboxes)?; let handle = UdsRouterHandle::new(handle_ctx, self.main_addr.clone(), self.api_addr.clone()); @@ -85,13 +94,17 @@ impl UdsRouter { impl UdsRouter { /// Handles any [`UdsRouterRequest::Connect`] messages received by /// this node's worker - async fn handle_connect(&mut self, peer: String) -> Result
{ + fn handle_connect(&mut self, peer: String) -> Result
{ let (peer_addr, pathnames) = UdsRouterHandle::resolve_peer(peer)?; - let router_handle = self.create_self_handle().await?; - let pair = - UdsSendWorker::start_pair(&self.ctx, router_handle, None, peer_addr, pathnames.clone()) - .await?; + let router_handle = self.create_self_handle()?; + let pair = UdsSendWorker::start_pair( + &self.ctx, + router_handle, + None, + peer_addr, + pathnames.clone(), + )?; let path = match pair.peer().as_pathname() { Some(p) => p, @@ -112,7 +125,7 @@ impl UdsRouter { accepts.extend(pathnames.iter().map(|p| Address::new_with_string(UDS, p))); let self_addr = pair.tx_addr(); - self.handle_register(accepts, self_addr.clone()).await?; + self.handle_register(accepts, self_addr.clone())?; Ok(self_addr) } @@ -132,14 +145,14 @@ impl UdsRouter { self.handle_unregister(self_address.clone()).await?; - self.ctx.stop_worker(self_address).await?; + self.ctx.stop_address(&self_address)?; Ok(()) } /// Handles any [`UdsRouterRequest::Register`] messages received by /// this node's worker - async fn handle_register(&mut self, accepts: Vec
, self_addr: Address) -> Result<()> { + fn handle_register(&mut self, accepts: Vec
, self_addr: Address) -> Result<()> { if accepts.is_empty() { error!("UDS registration request failed due to an invalid address list. Please provide at least one valid Address."); } @@ -190,10 +203,10 @@ impl UdsRouter { let onward = msg.next_on_onward_route()?; // Resolve route to the connection worker responsible for the next hop - let next = self.resolve_route(&onward).await?; + let next = self.resolve_route(onward)?; // Modify the transport message route - let msg = msg.replace_front_onward_route(&next)?; + let msg = msg.replace_front_onward_route(next.clone())?; // Send the local message to the connection worker ctx.send(next.clone(), msg).await?; @@ -204,7 +217,7 @@ impl UdsRouter { impl UdsRouter { /// Resolve the route to the provided noward address - async fn resolve_route(&mut self, onward: &Address) -> Result
{ + fn resolve_route(&mut self, onward: &Address) -> Result
{ // Check if the connection already exists if let Some(n) = self.map.get(onward) { return Ok(n.clone()); @@ -242,7 +255,7 @@ impl UdsRouter { } if self.allow_auto_connection { - self.handle_connect(peer).await + self.handle_connect(peer) } else { error!( "Failed to resolve route, no existing connection to peer: {}", @@ -258,11 +271,6 @@ impl Worker for UdsRouter { type Context = Context; type Message = Any; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await?; - Ok(()) - } - async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { let return_route = msg.return_route().clone(); let msg_addr = msg.msg_addr(); @@ -273,13 +281,13 @@ impl Worker for UdsRouter { let msg = UdsRouterRequest::decode(msg.payload())?; match msg { UdsRouterRequest::Register { accepts, self_addr } => { - let res = self.handle_register(accepts, self_addr).await; + let res = self.handle_register(accepts, self_addr); ctx.send(return_route, UdsRouterResponse::Register(res)) .await?; } UdsRouterRequest::Connect { peer } => { - let res = self.handle_connect(peer).await; + let res = self.handle_connect(peer); ctx.send(return_route, UdsRouterResponse::Connect(res)) .await?; diff --git a/implementations/rust/ockam/ockam_transport_uds/src/transport.rs b/implementations/rust/ockam/ockam_transport_uds/src/transport.rs index 040788ac328..a6cb9868614 100644 --- a/implementations/rust/ockam/ockam_transport_uds/src/transport.rs +++ b/implementations/rust/ockam/ockam_transport_uds/src/transport.rs @@ -1,6 +1,6 @@ use std::os::unix::net::SocketAddr; -use ockam_core::{async_trait, Address, AsyncTryClone, Result}; +use ockam_core::{async_trait, Address, Result, TryClone}; use ockam_node::{Context, HasContext}; use crate::{ @@ -28,7 +28,7 @@ use crate::{ /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { -/// let uds = UdsTransport::create(&ctx).await?; +/// let uds = UdsTransport::create(&ctx)?; /// uds.listen("/tmp/example-socket").await?; // Listen on socket `/tmp/example-socket` /// uds.connect("/tmp/other-socket").await?; // And connect to `/tmp/other-socket` /// # Ok(()) } @@ -41,21 +41,21 @@ use crate::{ /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { -/// let uds = UdsTransport::create(&ctx).await?; +/// let uds = UdsTransport::create(&ctx)?; /// uds.listen("/tmp/socket-one").await?; // Listen on `/tmp/socket-one` /// uds.listen("/tmp/socket-two").await?; // Listen on `/tmp/socket-two` /// # Ok(()) } /// ``` -#[derive(AsyncTryClone)] -#[async_try_clone(crate = "ockam_core")] +#[derive(TryClone)] +#[try_clone(crate = "ockam_core")] pub struct UdsTransport { router_handle: UdsRouterHandle, } impl UdsTransport { /// Creates a a UDS Router and registers it with the given node [`Context`] - pub async fn create(ctx: &Context) -> Result { - let router = UdsRouter::register(ctx).await?; + pub fn create(ctx: &Context) -> Result { + let router = UdsRouter::register(ctx)?; Ok(Self { router_handle: router, @@ -69,7 +69,7 @@ impl UdsTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let uds = UdsTransport::create(&ctx).await?; + /// let uds = UdsTransport::create(&ctx)?; /// uds.connect("/tmp/socket-name").await?; /// # Ok(()) } /// ``` @@ -84,7 +84,7 @@ impl UdsTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let uds = UdsTransport::create(&ctx).await?; + /// let uds = UdsTransport::create(&ctx)?; /// uds.connect("/tmp/socket-name").await?; /// /// uds.disconnect("/tmp/socket-name").await?; @@ -101,13 +101,13 @@ impl UdsTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let uds = UdsTransport::create(&ctx).await?; + /// let uds = UdsTransport::create(&ctx)?; /// uds.listen("/tmp/socket-name").await?; /// # Ok(()) } /// ``` pub async fn listen>(&self, bind_addr: S) -> Result { let sock_addr = parse_socket_addr(bind_addr.as_ref())?; - self.router_handle.bind(sock_addr).await + self.router_handle.bind(sock_addr) } } @@ -117,7 +117,7 @@ impl UdsTransport { pub trait UdsTransportExtension: HasContext { /// Create a UDS transport async fn create_uds_transport(&self) -> Result { - UdsTransport::create(self.get_context()).await + UdsTransport::create(self.get_context()) } } diff --git a/implementations/rust/ockam/ockam_transport_uds/src/workers/listener.rs b/implementations/rust/ockam/ockam_transport_uds/src/workers/listener.rs index c4138cdb4c0..ff5d649326b 100644 --- a/implementations/rust/ockam/ockam_transport_uds/src/workers/listener.rs +++ b/implementations/rust/ockam/ockam_transport_uds/src/workers/listener.rs @@ -1,8 +1,8 @@ use std::os::unix::net::SocketAddr; use ockam_core::{ - async_trait, compat::sync::Arc, Address, AllowSourceAddress, AsyncTryClone, DenyAll, Mailbox, - Mailboxes, Processor, Result, + async_trait, compat::sync::Arc, Address, AllowSourceAddress, DenyAll, Mailbox, Mailboxes, + Processor, Result, TryClone, }; use ockam_node::{Context, WorkerBuilder}; @@ -25,7 +25,7 @@ impl UdsListenProcessor { /// Binds a UDS socket at the given [`SocketAddr`] /// /// Starts a [`Processor`] which listens for incoming connections to accept. - pub(crate) async fn start( + pub(crate) fn start( ctx: &Context, router_handle: UdsRouterHandle, addr: SocketAddr, @@ -49,8 +49,7 @@ impl UdsListenProcessor { router_handle, }; - ctx.start_processor(Address::random_tagged("UdsListenProcessor"), processor) - .await?; + ctx.start_processor(Address::random_tagged("UdsListenProcessor"), processor)?; Ok(std_sock_addr) } @@ -60,10 +59,6 @@ impl UdsListenProcessor { impl Processor for UdsListenProcessor { type Context = Context; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await - } - /// Listen for and accept incoming UDS connections. /// /// Register the peers socket address, and create a worker to communicate with the peer. @@ -75,11 +70,11 @@ impl Processor for UdsListenProcessor { debug!("UDS connection accepted"); // Create a connection working - let handle_clone = self.router_handle.async_try_clone().await?; + let handle_clone = self.router_handle.try_clone()?; let local_addr = stream.local_addr().map_err(TransportError::from)?; let std_sock_addr = std_socket_addr_from_tokio(&local_addr)?; let (send_worker, pair) = - UdsSendWorker::new_pair(handle_clone, Some(stream), std_sock_addr, vec![]).await?; + UdsSendWorker::new_pair(handle_clone, Some(stream), std_sock_addr, vec![])?; self.router_handle.register(&pair).await?; debug!("UDS connection registered"); @@ -92,12 +87,14 @@ impl Processor for UdsListenProcessor { let tx_mailbox = Mailbox::new( pair.tx_addr(), + None, Arc::new(AllowSourceAddress(self.router_handle.main_addr().clone())), Arc::new(DenyAll), ); let internal_mailbox = Mailbox::new( send_worker.internal_addr().clone(), + None, Arc::new(AllowSourceAddress(send_worker.rx_addr().clone())), Arc::new(DenyAll), ); @@ -105,8 +102,7 @@ impl Processor for UdsListenProcessor { let mailboxes = Mailboxes::new(tx_mailbox, vec![internal_mailbox]); WorkerBuilder::new(send_worker) .with_mailboxes(mailboxes) - .start(ctx) - .await?; + .start(ctx)?; Ok(true) } diff --git a/implementations/rust/ockam/ockam_transport_uds/src/workers/receiver.rs b/implementations/rust/ockam/ockam_transport_uds/src/workers/receiver.rs index bee1fd79e97..2b5782d6122 100644 --- a/implementations/rust/ockam/ockam_transport_uds/src/workers/receiver.rs +++ b/implementations/rust/ockam/ockam_transport_uds/src/workers/receiver.rs @@ -36,10 +36,6 @@ impl UdsRecvProcessor { impl Processor for UdsRecvProcessor { type Context = Context; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await - } - /// Get the next message from the connection if there are any /// available and forward it to the next hop in the route. async fn process(&mut self, ctx: &mut Context) -> Result { @@ -90,7 +86,7 @@ impl Processor for UdsRecvProcessor { // Insert the peer address into the return route so that // reply routing can be properly resolved - msg = msg.push_front_return_route(&self.peer_addr); + msg = msg.push_front_return_route(self.peer_addr.clone()); trace!("Message onward route: {}", msg.onward_route()); trace!("Message return route: {}", msg.return_route()); diff --git a/implementations/rust/ockam/ockam_transport_uds/src/workers/sender.rs b/implementations/rust/ockam/ockam_transport_uds/src/workers/sender.rs index 86ee9e74fa6..999e27fc329 100644 --- a/implementations/rust/ockam/ockam_transport_uds/src/workers/sender.rs +++ b/implementations/rust/ockam/ockam_transport_uds/src/workers/sender.rs @@ -99,7 +99,7 @@ impl UdsSendWorker { } /// Create a ([`UdsSendWorker`],[`WorkerPair`]) without spawning the worker. - pub(crate) async fn new_pair( + pub(crate) fn new_pair( router_handle: UdsRouterHandle, stream: Option, peer: SocketAddr, @@ -126,7 +126,7 @@ impl UdsSendWorker { } /// Create a ([`UdsSendWorker`],[`WorkerPair`]) while spawning and starting the worker. - pub(crate) async fn start_pair( + pub(crate) fn start_pair( ctx: &Context, router_handle: UdsRouterHandle, stream: Option, @@ -136,32 +136,35 @@ impl UdsSendWorker { let udsrouter_main_addr = router_handle.main_addr().clone(); trace!("Creating new UDS worker pair"); - let (worker, pair) = Self::new_pair(router_handle, stream, peer, hostnames).await?; + let (worker, pair) = Self::new_pair(router_handle, stream, peer, hostnames)?; let tx_mailbox = Mailbox::new( pair.tx_addr(), + None, Arc::new(ockam_core::AllowSourceAddress(udsrouter_main_addr)), Arc::new(ockam_core::DenyAll), ); let internal_mailbox = Mailbox::new( worker.internal_addr().clone(), + None, Arc::new(ockam_core::AllowSourceAddress(worker.rx_addr().clone())), Arc::new(ockam_core::DenyAll), ); WorkerBuilder::new(worker) .with_mailboxes(Mailboxes::new(tx_mailbox, vec![internal_mailbox])) - .start(ctx) - .await?; + .start(ctx)?; Ok(pair) } async fn stop_and_unregister(&self, ctx: &Context) -> Result<()> { - self.router_handle.unregister(ctx.address()).await?; + self.router_handle + .unregister(ctx.primary_address().clone()) + .await?; - ctx.stop_worker(ctx.address()).await?; + ctx.stop_address(ctx.primary_address())?; Ok(()) } @@ -176,8 +179,6 @@ impl Worker for UdsSendWorker { /// /// Spawn a UDS Recceiver worker to processes incoming UDS messages async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await?; - let path = match self.peer.as_pathname() { Some(p) => p, None => { @@ -228,15 +229,14 @@ impl Worker for UdsSendWorker { self.internal_addr.clone(), ); - ctx.start_processor_with_access_control(self.rx_addr.clone(), receiver, DenyAll, AllowAll) - .await?; + ctx.start_processor_with_access_control(self.rx_addr.clone(), receiver, DenyAll, AllowAll)?; Ok(()) } async fn shutdown(&mut self, ctx: &mut Self::Context) -> Result<()> { if self.rx_should_be_stopped { - let _ = ctx.stop_processor(self.rx_addr().clone()).await; + let _ = ctx.stop_address(self.rx_addr()); } Ok(()) diff --git a/implementations/rust/ockam/ockam_transport_websocket/README.md b/implementations/rust/ockam/ockam_transport_websocket/README.md index aa8bde82a53..6c3a9bfe9af 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/README.md +++ b/implementations/rust/ockam/ockam_transport_websocket/README.md @@ -39,11 +39,11 @@ use ockam_macros::node; #[ockam_macros::node(crate = "ockam_node")] async fn main(mut ctx: Context) -> Result<()> {//! - let ws = WebSocketTransport::create(&ctx).await?; + let ws = WebSocketTransport::create(&ctx)?; ws.listen("localhost:8000").await?; // Listen on port 8000 // Start a worker, of type MyWorker, at address "my_worker" - ctx.start_worker("my_worker", MyWorker).await?; + ctx.start_worker("my_worker", MyWorker)?; // Run worker indefinitely in the background Ok(()) @@ -61,7 +61,7 @@ use ockam_macros::node; #[ockam_macros::node(crate = "ockam_node")] async fn main(mut ctx: Context) -> Result<()> { use ockam_node::MessageReceiveOptions; -let ws = WebSocketTransport::create(&ctx).await?; + let ws = WebSocketTransport::create(&ctx)?; // Define the route to the server's worker. let r = route![(WS, "localhost:8000"), "my_worker"]; @@ -73,7 +73,7 @@ let ws = WebSocketTransport::create(&ctx).await?; let reply = ctx.receive::().await?; // Stop all workers, stop the node, cleanup and return. - ctx.stop().await + ctx.shutdown_node().await } ``` diff --git a/implementations/rust/ockam/ockam_transport_websocket/src/lib.rs b/implementations/rust/ockam/ockam_transport_websocket/src/lib.rs index 8a129b02726..82fda1def0b 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/src/lib.rs +++ b/implementations/rust/ockam/ockam_transport_websocket/src/lib.rs @@ -29,11 +29,11 @@ //! //! #[ockam_macros::node(crate = "ockam_node")] //! async fn main(mut ctx: Context) -> Result<()> {//! -//! let ws = WebSocketTransport::create(&ctx).await?; +//! let ws = WebSocketTransport::create(&ctx)?; //! ws.listen("localhost:8000").await?; // Listen on port 8000 //! //! // Start a worker, of type MyWorker, at address "my_worker" -//! ctx.start_worker("my_worker", MyWorker).await?; +//! ctx.start_worker("my_worker", MyWorker)?; //! //! // Run worker indefinitely in the background //! Ok(()) @@ -51,7 +51,7 @@ //! #[ockam_macros::node(crate = "ockam_node")] //! async fn main(mut ctx: Context) -> Result<()> { //! use ockam_node::MessageReceiveOptions; -//! let ws = WebSocketTransport::create(&ctx).await?; +//! let ws = WebSocketTransport::create(&ctx)?; //! //! // Define the route to the server's worker. //! let r = route![(WS, "localhost:8000"), "my_worker"]; @@ -63,7 +63,7 @@ //! let reply = ctx.receive::().await?; //! //! // Stop all workers, stop the node, cleanup and return. -//! ctx.stop().await +//! ctx.shutdown_node().await //! } //! ``` //! @@ -101,8 +101,6 @@ mod workers; /// WebSocket address type constant. pub const WS: TransportType = TransportType::new(3); -pub(crate) const CLUSTER_NAME: &str = "_internals.transport.ws"; - fn parse_socket_addr>(s: S) -> Result { Ok(s.as_ref() .parse() diff --git a/implementations/rust/ockam/ockam_transport_websocket/src/router/handle.rs b/implementations/rust/ockam/ockam_transport_websocket/src/router/handle.rs index aaa9a4caf45..608fdb43ecc 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/src/router/handle.rs +++ b/implementations/rust/ockam/ockam_transport_websocket/src/router/handle.rs @@ -1,7 +1,7 @@ use core::str::FromStr; use std::net::{SocketAddr, ToSocketAddrs}; -use ockam_core::{async_trait, Address, AsyncTryClone, DenyAll, Result}; +use ockam_core::{Address, Result, TryClone}; use ockam_node::Context; use ockam_transport_core::TransportError; @@ -12,26 +12,13 @@ use crate::{parse_socket_addr, WebSocketAddress}; /// A handle to connect to a WebSocketRouter. /// /// Dropping this handle is harmless. +#[derive(TryClone)] +#[try_clone(crate = "ockam_core")] pub(crate) struct WebSocketRouterHandle { ctx: Context, api_addr: Address, } -#[async_trait] -impl AsyncTryClone for WebSocketRouterHandle { - async fn async_try_clone(&self) -> Result { - let child_ctx = self - .ctx - .new_detached( - Address::random_tagged("WebSocketRouterHandle.async_try_clone.detached"), - DenyAll, - DenyAll, - ) - .await?; - Ok(Self::new(child_ctx, self.api_addr.clone())) - } -} - impl WebSocketRouterHandle { pub(crate) fn new(ctx: Context, api_addr: Address) -> Self { Self { ctx, api_addr } @@ -64,7 +51,7 @@ impl WebSocketRouterHandle { /// Bind an incoming connection listener for this router. pub(crate) async fn bind(&self, addr: impl Into) -> Result { let socket_addr = addr.into(); - WebSocketListenProcessor::start(&self.ctx, self.async_try_clone().await?, socket_addr).await + WebSocketListenProcessor::start(&self.ctx, self.try_clone()?, socket_addr).await } /// Return the peer's `SocketAddr` and `hostnames` given a plain `String` address. @@ -103,7 +90,7 @@ impl WebSocketRouterHandle { // Create a new `WorkerPair` for the given peer, initializing a new pair // of sender worker and receiver processor. - let pair = WorkerPair::from_client(&self.ctx, peer_addr, hostnames).await?; + let pair = WorkerPair::from_client(&self.ctx, peer_addr, hostnames)?; // Handle node's register request. self.register(&pair).await diff --git a/implementations/rust/ockam/ockam_transport_websocket/src/router/mod.rs b/implementations/rust/ockam/ockam_transport_websocket/src/router/mod.rs index 049c9234ec0..a364dd78e5e 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/src/router/mod.rs +++ b/implementations/rust/ockam/ockam_transport_websocket/src/router/mod.rs @@ -51,7 +51,7 @@ pub(crate) struct WebSocketRouter { impl WebSocketRouter { /// Create and register a new WebSocket router with the node context. - pub(crate) async fn register(ctx: &Context) -> Result { + pub(crate) fn register(ctx: &Context) -> Result { let main_addr = Address::random_tagged("WebSocketRouter.main_addr"); let api_addr = Address::random_tagged("WebSocketRouter.api_addr"); debug!( @@ -67,7 +67,7 @@ impl WebSocketRouter { Mailbox::deny_all(Address::random_tagged("WebSocketRouter.detached")), vec![], ); - let child_ctx = ctx.new_detached_with_mailboxes(mailboxes).await?; + let child_ctx = ctx.new_detached_with_mailboxes(mailboxes)?; let router = Self { ctx: child_ctx, main_addr: main_addr.clone(), @@ -76,36 +76,37 @@ impl WebSocketRouter { allow_auto_connection: true, }; - let handle = router.create_self_handle(ctx).await?; + let handle = router.create_self_handle(ctx)?; let mailboxes = Mailboxes::new( Mailbox::new( main_addr.clone(), + None, Arc::new(AllowAll), // FIXME: @ac Arc::new(AllowAll), // FIXME: @ac ), vec![Mailbox::new( api_addr, + None, Arc::new(AllowAll), // FIXME: @ac Arc::new(AllowAll), // FIXME: @ac )], ); WorkerBuilder::new(router) .with_mailboxes(mailboxes) - .start(ctx) - .await?; + .start(ctx)?; trace!("Registering WS router for type = {}", WS); ctx.register(WS, main_addr)?; Ok(handle) } - async fn create_self_handle(&self, ctx: &Context) -> Result { + fn create_self_handle(&self, ctx: &Context) -> Result { let mailboxes = Mailboxes::new( Mailbox::deny_all(Address::random_tagged("WebSocketRouter.handle")), vec![], ); - let handle_ctx = ctx.new_detached_with_mailboxes(mailboxes).await?; + let handle_ctx = ctx.new_detached_with_mailboxes(mailboxes)?; let handle = WebSocketRouterHandle::new(handle_ctx, self.api_addr.clone()); Ok(handle) } @@ -116,11 +117,6 @@ impl Worker for WebSocketRouter { type Message = Any; type Context = Context; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await?; - Ok(()) - } - async fn handle_message(&mut self, ctx: &mut Context, msg: Routed) -> Result<()> { let return_route = msg.return_route().clone(); let msg_addr = msg.msg_addr(); @@ -132,7 +128,7 @@ impl Worker for WebSocketRouter { match msg { WebSocketRouterRequest::Register { accepts, self_addr } => { trace!("handle_message register: {:?} => {:?}", accepts, self_addr); - let res = self.handle_register(accepts, self_addr).await; + let res = self.handle_register(accepts, self_addr); ctx.send_from_address( return_route, @@ -171,13 +167,13 @@ impl WebSocketRouter { // TODO: Check if this is the hostname and we have existing/pending connection to this IP if self.allow_auto_connection { - next = self.connect(peer_str).await?; + next = self.connect(peer_str)?; } else { return Err(TransportError::UnknownRoute)?; } } - let msg = msg.replace_front_onward_route(&next)?; + let msg = msg.replace_front_onward_route(next.clone())?; // Send the transport message to the connection worker ctx.send(next.clone(), msg).await?; @@ -185,7 +181,7 @@ impl WebSocketRouter { Ok(()) } - async fn handle_register(&mut self, accepts: Vec
, self_addr: Address) -> Result<()> { + fn handle_register(&mut self, accepts: Vec
, self_addr: Address) -> Result<()> { // The `accepts` vector should always contain at least one address. if let Some(f) = accepts.first().cloned() { trace!("WS registration request: {} => {}", f, self_addr); @@ -218,13 +214,13 @@ impl WebSocketRouter { Ok(()) } - async fn connect(&mut self, peer: String) -> Result
{ + fn connect(&mut self, peer: String) -> Result
{ // Get peer address and connect to it. let (peer_addr, hostnames) = WebSocketRouterHandle::resolve_peer(peer)?; // Create a new `WorkerPair` for the given peer, initializing a new pair // of sender worker and receiver processor. - let pair = WorkerPair::from_client(&self.ctx, peer_addr, hostnames).await?; + let pair = WorkerPair::from_client(&self.ctx, peer_addr, hostnames)?; // Handle node's register request. let mut accepts = vec![pair.peer()]; @@ -235,7 +231,7 @@ impl WebSocketRouter { .map(|addr| addr.into()), ); let self_addr = pair.tx_addr(); - self.handle_register(accepts, self_addr.clone()).await?; + self.handle_register(accepts, self_addr.clone())?; Ok(self_addr) } diff --git a/implementations/rust/ockam/ockam_transport_websocket/src/transport.rs b/implementations/rust/ockam/ockam_transport_websocket/src/transport.rs index e67095e7cc0..614abe2bb8a 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/src/transport.rs +++ b/implementations/rust/ockam/ockam_transport_websocket/src/transport.rs @@ -27,7 +27,7 @@ use crate::{parse_socket_addr, WebSocketRouter, WebSocketRouterHandle, WS}; /// # use ockam_core::Result; /// # use ockam_node::Context; /// # async fn test(ctx: Context) -> Result<()> { -/// let ws = WebSocketTransport::create(&ctx).await?; +/// let ws = WebSocketTransport::create(&ctx)?; /// ws.listen("127.0.0.1:8000").await?; // Listen on port 8000 /// ws.connect("127.0.0.1:5000").await?; // And connect to port 5000 /// # Ok(()) } @@ -40,7 +40,7 @@ use crate::{parse_socket_addr, WebSocketRouter, WebSocketRouterHandle, WS}; /// # use ockam_core::{Address, Result}; /// # use ockam_node::Context; /// # async fn test(ctx: Context) -> Result<()> { -/// let ws = WebSocketTransport::create(&ctx).await?; +/// let ws = WebSocketTransport::create(&ctx)?; /// ws.listen("127.0.0.1:8000").await?; // Listen on port 8000 /// ws.listen("127.0.0.1:9000").await?; // Listen on port 9000 /// # Ok(()) } @@ -57,11 +57,11 @@ impl WebSocketTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let ws = WebSocketTransport::create(&ctx).await?; + /// let ws = WebSocketTransport::create(&ctx)?; /// # Ok(()) } /// ``` - pub async fn create(ctx: &Context) -> Result { - let router_handle = WebSocketRouter::register(ctx).await?; + pub fn create(ctx: &Context) -> Result { + let router_handle = WebSocketRouter::register(ctx)?; Ok(Self { router_handle }) } @@ -72,7 +72,7 @@ impl WebSocketTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let ws = WebSocketTransport::create(&ctx).await?; + /// let ws = WebSocketTransport::create(&ctx)?; /// ws.listen("127.0.0.1:8000").await?; // Listen on port 8000 /// ws.connect("127.0.0.1:5000").await?; // and connect to port 5000 /// # Ok(()) } @@ -93,7 +93,7 @@ impl WebSocketTransport { /// # use ockam_node::Context; /// # use ockam_core::Result; /// # async fn test(ctx: Context) -> Result<()> { - /// let ws = WebSocketTransport::create(&ctx).await?; + /// let ws = WebSocketTransport::create(&ctx)?; /// ws.listen("127.0.0.1:8000").await?; /// # Ok(()) } pub async fn listen>(&self, bind_addr: S) -> Result { @@ -108,7 +108,7 @@ impl WebSocketTransport { pub trait WebSocketTransportExtension: HasContext { /// Create a WebSocket transport async fn create_web_socket_transport(&self) -> Result { - WebSocketTransport::create(self.get_context()).await + WebSocketTransport::create(self.get_context()) } } diff --git a/implementations/rust/ockam/ockam_transport_websocket/src/workers/listener.rs b/implementations/rust/ockam/ockam_transport_websocket/src/workers/listener.rs index ff4d47cbf29..6888a51879a 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/src/workers/listener.rs +++ b/implementations/rust/ockam/ockam_transport_websocket/src/workers/listener.rs @@ -38,8 +38,7 @@ impl WebSocketListenProcessor { ctx.start_processor_with_access_control( waddr, processor, AllowAll, // FIXME: @ac AllowAll, // FIXME: @ac - ) - .await?; + )?; Ok(saddr) } } @@ -48,10 +47,6 @@ impl WebSocketListenProcessor { impl Processor for WebSocketListenProcessor { type Context = Context; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await - } - async fn process(&mut self, ctx: &mut Self::Context) -> Result { debug!("Waiting for incoming TCP connection..."); @@ -63,7 +58,7 @@ impl Processor for WebSocketListenProcessor { debug!("TCP connection accepted"); // Spawn a connection worker for it - let pair = WorkerPair::from_server(ctx, ws_stream, peer, vec![]).await?; + let pair = WorkerPair::from_server(ctx, ws_stream, peer, vec![])?; // Register the connection with the local TcpRouter self.router_handle.register(&pair).await?; diff --git a/implementations/rust/ockam/ockam_transport_websocket/src/workers/receiver.rs b/implementations/rust/ockam/ockam_transport_websocket/src/workers/receiver.rs index 5c7e1b06d6e..4113292f1e4 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/src/workers/receiver.rs +++ b/implementations/rust/ockam/ockam_transport_websocket/src/workers/receiver.rs @@ -45,10 +45,6 @@ where { type Context = Context; - async fn initialize(&mut self, ctx: &mut Context) -> Result<()> { - ctx.set_cluster(crate::CLUSTER_NAME).await - } - /// Get next message from the WebSocket stream if there is /// any available, and forward it to the next hop in the route. async fn process(&mut self, ctx: &mut Context) -> Result { @@ -89,7 +85,7 @@ where // Insert the peer address into the return route so that // reply routing can be properly resolved - msg = msg.push_front_return_route(&self.peer_addr); + msg = msg.push_front_return_route(self.peer_addr.clone()); // Some verbose logging we may want to remove trace!("Message onward route: {}", msg.onward_route()); diff --git a/implementations/rust/ockam/ockam_transport_websocket/src/workers/sender.rs b/implementations/rust/ockam/ockam_transport_websocket/src/workers/sender.rs index 0449da48039..2a402cabd3b 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/src/workers/sender.rs +++ b/implementations/rust/ockam/ockam_transport_websocket/src/workers/sender.rs @@ -42,7 +42,7 @@ impl WorkerPair { /// returns a `WorkerPair` instance that will be registered by the `WebSocketRouter`. /// /// The WebSocket stream is created when the `WebSocketSendWorker` is initialized. - pub(crate) async fn from_client( + pub(crate) fn from_client( ctx: &Context, peer: SocketAddr, hostnames: Vec, @@ -53,7 +53,7 @@ impl WorkerPair { let sender = WebSocketSendWorker::::new( peer, internal_addr.clone(), - DelayedEvent::create(ctx, internal_addr.clone(), vec![]).await?, + DelayedEvent::create(ctx, internal_addr.clone(), vec![])?, ); let tx_addr = Address::random_tagged("WebSocketSender.tx_addr.from_client"); @@ -61,19 +61,20 @@ impl WorkerPair { let mailboxes = Mailboxes::new( Mailbox::new( tx_addr.clone(), + None, Arc::new(AllowAll), // FIXME: @ac Arc::new(AllowAll), // FIXME: @ac ), vec![Mailbox::new( internal_addr, + None, Arc::new(AllowAll), // FIXME: @ac Arc::new(AllowAll), // FIXME: @ac )], ); WorkerBuilder::new(sender) .with_mailboxes(mailboxes) - .start(ctx) - .await?; + .start(ctx)?; // Return a handle to the worker pair Ok(WorkerPair { @@ -85,7 +86,7 @@ impl WorkerPair { /// Spawn instances of `WebSocketSendWorker` and `WebSocketRecvProcessor` and /// returns a `WorkerPair` instance that will be registered by the `WebSocketRouter`. - pub(crate) async fn from_server( + pub(crate) fn from_server( ctx: &Context, stream: WebSocketStream, peer: SocketAddr, @@ -98,26 +99,27 @@ impl WorkerPair { stream, peer, internal_addr.clone(), - DelayedEvent::create(ctx, internal_addr.clone(), vec![]).await?, + DelayedEvent::create(ctx, internal_addr.clone(), vec![])?, ); let tx_addr = Address::random_tagged("WebSocketSender.tx_addr.from_server"); let mailboxes = Mailboxes::new( Mailbox::new( tx_addr.clone(), + None, Arc::new(AllowAll), // FIXME: @ac Arc::new(AllowAll), // FIXME: @ac ), vec![Mailbox::new( internal_addr, + None, Arc::new(AllowAll), // FIXME: @ac Arc::new(AllowAll), // FIXME: @ac )], ); WorkerBuilder::new(sender) .with_mailboxes(mailboxes) - .start(ctx) - .await?; + .start(ctx)?; // Return a handle to the worker pair Ok(WorkerPair { @@ -149,7 +151,7 @@ impl WebSocketSendWorker where S: AsyncStream, { - async fn handle_initialize(&mut self, ctx: &mut Context) -> Result<()> { + fn handle_initialize(&mut self, ctx: &mut Context) -> Result<()> { if let Some(ws_stream) = self.ws_stream.take() { let rx_addr = Address::random_tagged("WebSocketSendWorker.rx_addr"); let receiver = WebSocketRecvProcessor::new(ws_stream, self.peer); @@ -158,24 +160,22 @@ where receiver, AllowAll, // FIXME: @ac AllowAll, // FIXME: @ac - ) - .await?; + )?; } else { return Err(TransportError::GenericIo)?; } - ctx.set_cluster(crate::CLUSTER_NAME).await?; - self.schedule_heartbeat().await?; + self.schedule_heartbeat()?; Ok(()) } - async fn schedule_heartbeat(&mut self) -> Result<()> { + fn schedule_heartbeat(&mut self) -> Result<()> { let heartbeat_interval = match &self.heartbeat_interval { Some(hi) => *hi, None => return Ok(()), }; - self.heartbeat.schedule(heartbeat_interval).await + self.heartbeat.schedule(heartbeat_interval) } /// Receive messages from the `WebSocketRouter` to send @@ -199,7 +199,7 @@ where .is_err() { warn!("Failed to send heartbeat to peer {}", self.peer); - ctx.stop_worker(ctx.address()).await?; + ctx.stop_address(ctx.primary_address())?; return Ok(()); } @@ -214,13 +214,13 @@ where let msg = WebSocketMessage::from(msg.into_transport_message().encode()?); if ws_sink.send(msg).await.is_err() { warn!("Failed to send message to peer {}", self.peer); - ctx.stop_worker(ctx.address()).await?; + ctx.stop_address(ctx.primary_address())?; return Ok(()); } debug!("Sent message to peer {}", self.peer); } - self.schedule_heartbeat().await?; + self.schedule_heartbeat()?; Ok(()) } @@ -277,7 +277,7 @@ impl Worker for WebSocketSendWorker { type Context = Context; async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { - self.handle_initialize(ctx).await?; + self.handle_initialize(ctx)?; Ok(()) } @@ -297,7 +297,7 @@ impl Worker for WebSocketSendWorker { async fn initialize(&mut self, ctx: &mut Self::Context) -> Result<()> { self.initialize_stream().await?; - self.handle_initialize(ctx).await?; + self.handle_initialize(ctx)?; Ok(()) } diff --git a/implementations/rust/ockam/ockam_transport_websocket/tests/send_receive.rs b/implementations/rust/ockam/ockam_transport_websocket/tests/send_receive.rs index 411b5b4be9e..2f108b74343 100644 --- a/implementations/rust/ockam/ockam_transport_websocket/tests/send_receive.rs +++ b/implementations/rust/ockam/ockam_transport_websocket/tests/send_receive.rs @@ -7,9 +7,9 @@ use ockam_transport_websocket::{WebSocketTransport, WS}; #[ignore] #[ockam_macros::test] async fn send_receive(ctx: &mut Context) -> Result<()> { - let transport = WebSocketTransport::create(ctx).await?; + let transport = WebSocketTransport::create(ctx)?; let listener_address = transport.listen("127.0.0.1:0").await?; - ctx.start_worker("echoer", Echoer).await?; + ctx.start_worker("echoer", Echoer)?; // Sender { diff --git a/tools/stress-test/src/main.rs b/tools/stress-test/src/main.rs index 2ddc048ec3f..b580280d98a 100644 --- a/tools/stress-test/src/main.rs +++ b/tools/stress-test/src/main.rs @@ -160,7 +160,7 @@ impl State { ctx: Arc, cli_state: &CliState, ) -> ockam::Result> { - let tcp = TcpTransport::create(&ctx).await?; + let tcp = TcpTransport::create(&ctx)?; let options = TcpListenerOptions::new(); let listener = tcp.listen(&"127.0.0.1:0", options).await?; @@ -189,11 +189,10 @@ impl State { ); let node_manager_worker = NodeManagerWorker::new(node_manager.clone()); - ctx.start_worker(NODEMANAGER_ADDR, node_manager_worker) - .await?; + ctx.start_worker(NODEMANAGER_ADDR, node_manager_worker)?; ctx.flow_controls() - .add_consumer(NODEMANAGER_ADDR, listener.flow_control_id()); + .add_consumer(&NODEMANAGER_ADDR.into(), listener.flow_control_id()); Ok(node_manager) } } diff --git a/tools/stress-test/src/portal_simulator.rs b/tools/stress-test/src/portal_simulator.rs index 93ea4aa0c30..b1ab0210276 100644 --- a/tools/stress-test/src/portal_simulator.rs +++ b/tools/stress-test/src/portal_simulator.rs @@ -8,7 +8,7 @@ use ockam::compat::tokio; use ockam::{Context, Processor, Route, Routed, Worker}; use ockam_api::nodes::InMemoryNode; use ockam_core::flow_control::FlowControlId; -use ockam_core::{async_trait, route, Address, AllowAll, DenyAll, NeutralMessage}; +use ockam_core::{async_trait, Address, AllowAll, DenyAll, NeutralMessage}; use ockam_multiaddr::MultiAddr; use crate::config::Throughput; @@ -45,7 +45,7 @@ pub async fn create( context .flow_controls() - .add_consumer(receiver_address.clone(), &relay_flow_control_id); + .add_consumer(&receiver_address, &relay_flow_control_id); let worker = PortalSimulatorReceiver { messages_out_of_order: portal_stats.messages_out_of_order.clone(), @@ -56,7 +56,6 @@ pub async fn create( context .start_worker(receiver_address.clone(), worker) - .await .unwrap(); let connection = node @@ -64,7 +63,7 @@ pub async fn create( .await?; let processor = PortalSimulatorSender { - to: route![connection.route()?, relay_address, receiver_address], + to: connection.route()? + relay_address + receiver_address, throughput, bytes_sent: portal_stats.bytes_sent.clone(), messages_sent: portal_stats.messages_sent.clone(), @@ -72,7 +71,6 @@ pub async fn create( context .start_processor_with_access_control(sender_address, processor, DenyAll, AllowAll) - .await .unwrap(); Ok(portal_stats)