From 38cd270800276c75c831a5b1fc0c97a01219eef4 Mon Sep 17 00:00:00 2001 From: Riccardo Gallo Date: Fri, 29 Nov 2024 17:40:12 +0100 Subject: [PATCH 1/3] refactor(uuid): specify the stream node uuid when using grpc connection use EVN ASTARTE_MSGHUB_NODE_ID or the toml file to specify the node id of the stream application Signed-off-by: Riccardo Gallo --- README.md | 2 ++ astarte-device-conf/config.toml | 1 + src/astarte.rs | 23 +++++++++++++++-------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index eddcef1..04e6835 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ If you want to use environment variables to set up the application, you can set - `ASTARTE_STORE_DIRECTORY`: path to the directory where to store data (e.g., in case of Astarte properties) - `ASTARTE_IGNORE_SSL_ERRORS`: boolean stating if SSL errors should be ignored (default: false) - `ASTARTE_MSGHUB_ENDPOINT`: endpoint of the Astarte Message Hub instance +- `ASTARTE_MSGHUB_NODE_ID`: UUID of the Node to connect to the Astarte Message Hub Instead, if you want to use a configuration file, you must specify its location by using the `ASTARTE_CONFIG_PATH` environment variable. The `config.toml` file must contain the following information: @@ -62,6 +63,7 @@ astarte_ignore_ssl = false # gRPC connection to the Astarte Message Hub [astarte.grpc] endpoint = "http://[::1]:50051" +node_id = "ASTARTE_MSGHUB_NODE_ID_HERE" ``` NOTE: only one of the `[astarte.mqtt]` or `[astarte.grpc]` sections should be specified in the file. diff --git a/astarte-device-conf/config.toml b/astarte-device-conf/config.toml index f4db64c..52b6771 100644 --- a/astarte-device-conf/config.toml +++ b/astarte-device-conf/config.toml @@ -27,3 +27,4 @@ astarte_ignore_ssl = false # #[astarte.grpc] #endpoint = "http://[::1]:50051" +#node_id = "ASTARTE_MSGHUB_NODE_ID_HERE" diff --git a/src/astarte.rs b/src/astarte.rs index aa88f9b..73f3a7d 100644 --- a/src/astarte.rs +++ b/src/astarte.rs @@ -21,9 +21,7 @@ use std::path::{Path, PathBuf}; use std::time::SystemTime; use std::{env, io}; use tracing::{debug, error}; - -/// Stream Rust test node identifier -const STREAM_RUST_TEST_NODE_UUID: uuid::Uuid = uuid::uuid!("d72a6187-7cf1-44cc-87e8-e991936166dc"); +use uuid::Uuid; const DEVICE_DATASTREAM: &str = include_str!("../interfaces/org.astarte-platform.genericsensors.Values.json"); @@ -103,9 +101,10 @@ impl ConnectionConfigBuilder { self.astarte_connection = Some(con); let endpoint = env::var("ASTARTE_MSGHUB_ENDPOINT")?; + let node_id = env::var("ASTARTE_MSGHUB_NODE_ID")?.parse::()?; // update the grpc config info - self.grpc_config = Some(GrpcConfigBuilder { endpoint }); + self.grpc_config = Some(GrpcConfigBuilder { node_id, endpoint }); } } @@ -162,10 +161,10 @@ impl ConnectionConfigBuilder { Ok((client, SdkConnection::Mqtt(connection))) } AstarteConnection::Grpc => { - let grpc_endpoint = self.grpc_config.ok_or_eyre("invalid grpc config")?.endpoint; - - let grpc_cfg = GrpcConfig::from_url(STREAM_RUST_TEST_NODE_UUID, grpc_endpoint) - .wrap_err("failed to create a gRPC config")?; + let grpc_cfg = self + .grpc_config + .ok_or_eyre("invalid grpc config")? + .build()?; debug!("parsed Astarte Message Hub config: {:#?}", grpc_cfg); @@ -224,10 +223,18 @@ impl From for MqttConfig { /// Config for a gRPC connection to an Astarte Message Hub instance #[derive(Debug, Default, Deserialize)] struct GrpcConfigBuilder { + /// Stream Rust test UUID + node_id: Uuid, /// The Endpoint of the Astarte Message Hub endpoint: String, } +impl GrpcConfigBuilder { + fn build(self) -> eyre::Result { + GrpcConfig::from_url(self.node_id, self.endpoint).wrap_err("failed to create a gRPC config") + } +} + /// Send data to Astarte pub async fn send_data( client: DeviceClient, From 78f86373d4617fa5dcd98c78b2338b1bef7a809b Mon Sep 17 00:00:00 2001 From: Riccardo Gallo Date: Mon, 2 Dec 2024 15:18:01 +0100 Subject: [PATCH 2/3] refactor(uuid): add default uuid in case of missing variable Signed-off-by: Riccardo Gallo --- src/astarte.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/astarte.rs b/src/astarte.rs index 73f3a7d..2023d40 100644 --- a/src/astarte.rs +++ b/src/astarte.rs @@ -21,11 +21,13 @@ use std::path::{Path, PathBuf}; use std::time::SystemTime; use std::{env, io}; use tracing::{debug, error}; -use uuid::Uuid; +use uuid::{uuid, Uuid}; const DEVICE_DATASTREAM: &str = include_str!("../interfaces/org.astarte-platform.genericsensors.Values.json"); +const DEFAULT_STREAM_NODE_ID: Uuid = uuid!("d72a6187-7cf1-44cc-87e8-e991936166dc"); + /// Specify which Astarte library use to connect to Astarte #[derive( Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, clap::ValueEnum, Deserialize, @@ -101,7 +103,9 @@ impl ConnectionConfigBuilder { self.astarte_connection = Some(con); let endpoint = env::var("ASTARTE_MSGHUB_ENDPOINT")?; - let node_id = env::var("ASTARTE_MSGHUB_NODE_ID")?.parse::()?; + let node_id = env::var("ASTARTE_MSGHUB_NODE_ID") + .map(|s| s.parse::().unwrap_or(DEFAULT_STREAM_NODE_ID)) + .unwrap_or(DEFAULT_STREAM_NODE_ID); // update the grpc config info self.grpc_config = Some(GrpcConfigBuilder { node_id, endpoint }); From 1f71c483c43209d298cafed93b131a4533371a31 Mon Sep 17 00:00:00 2001 From: Riccardo Gallo Date: Mon, 2 Dec 2024 17:57:42 +0100 Subject: [PATCH 3/3] refactor(uuid): add default uuid in case of missing variable Signed-off-by: Riccardo Gallo --- Cargo.toml | 2 +- README.md | 3 ++- src/astarte.rs | 22 ++++++++++++++++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d87a252..c51bd4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,4 +27,4 @@ tracing = "0.1.37" tracing-subscriber = { version = "0.3.0", features = ["env-filter"]} rand = "0.8.5" serde = { version = "1.0.207", features = ["derive"] } -uuid = { version = "1.10.0", features = ["v4"] } +uuid = { version = "1.10.0", features = ["v4", "serde"] } diff --git a/README.md b/README.md index 04e6835..092edb8 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ astarte_ignore_ssl = false # gRPC connection to the Astarte Message Hub [astarte.grpc] endpoint = "http://[::1]:50051" -node_id = "ASTARTE_MSGHUB_NODE_ID_HERE" +#node_id = "ASTARTE_MSGHUB_NODE_ID_HERE" ``` NOTE: only one of the `[astarte.mqtt]` or `[astarte.grpc]` sections should be specified in the file. @@ -78,6 +78,7 @@ A detailed description of the fields is depicted below: present, the credential secret will be used. - `astarte_ignore_ssl`: a flag stating if SSL errors should be ignored when connecting to Astarte. - `endpoint`: the endpoint where the Astarte Message Hub instance is listening for new connections. +- `node_id`: UUID of the Node to connect to the Astarte Message Hub (optional). Since the application can be configured with a CLI, when [running the application](#build-and-run) you can specify the type of connection (`mqtt` or `grpc`) and the path to the `config.toml` file with the `--astarte_connection` (`-c`) and diff --git a/src/astarte.rs b/src/astarte.rs index 2023d40..9e85e09 100644 --- a/src/astarte.rs +++ b/src/astarte.rs @@ -15,8 +15,9 @@ use astarte_device_sdk::transport::mqtt::{Credential, Mqtt, MqttConfig}; use astarte_device_sdk::{Client, DeviceClient, DeviceConnection}; use clap::ValueEnum; use color_eyre::eyre; -use color_eyre::eyre::{eyre, OptionExt, WrapErr}; +use color_eyre::eyre::{bail, eyre, OptionExt, WrapErr}; use serde::Deserialize; +use std::env::VarError; use std::path::{Path, PathBuf}; use std::time::SystemTime; use std::{env, io}; @@ -28,6 +29,11 @@ const DEVICE_DATASTREAM: &str = const DEFAULT_STREAM_NODE_ID: Uuid = uuid!("d72a6187-7cf1-44cc-87e8-e991936166dc"); +/// This function is necessary for serde deserialization +fn default_stream_node_id() -> Uuid { + DEFAULT_STREAM_NODE_ID +} + /// Specify which Astarte library use to connect to Astarte #[derive( Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, clap::ValueEnum, Deserialize, @@ -103,9 +109,16 @@ impl ConnectionConfigBuilder { self.astarte_connection = Some(con); let endpoint = env::var("ASTARTE_MSGHUB_ENDPOINT")?; - let node_id = env::var("ASTARTE_MSGHUB_NODE_ID") - .map(|s| s.parse::().unwrap_or(DEFAULT_STREAM_NODE_ID)) - .unwrap_or(DEFAULT_STREAM_NODE_ID); + + let node_id = match env::var("ASTARTE_MSGHUB_NODE_ID") { + Ok(uuid) => { + Uuid::parse_str(&uuid).wrap_err("invalid ASTARTE_MSGHUB_NODE_ID {uuid}")? + } + Err(VarError::NotPresent) => DEFAULT_STREAM_NODE_ID, + Err(VarError::NotUnicode(s)) => { + bail!("non unicode ASTARTE_MSGHUB_NODE_ID {s:?}") + } + }; // update the grpc config info self.grpc_config = Some(GrpcConfigBuilder { node_id, endpoint }); @@ -227,6 +240,7 @@ impl From for MqttConfig { /// Config for a gRPC connection to an Astarte Message Hub instance #[derive(Debug, Default, Deserialize)] struct GrpcConfigBuilder { + #[serde(default = "default_stream_node_id")] /// Stream Rust test UUID node_id: Uuid, /// The Endpoint of the Astarte Message Hub