summaryrefslogtreecommitdiffstats
path: root/tedge_config
diff options
context:
space:
mode:
authorRina Fujino <18257209+rina23q@users.noreply.github.com>2021-05-20 18:14:16 +0200
committerGitHub <noreply@github.com>2021-05-20 18:14:16 +0200
commit8418ccc07c00f2b38275021f2de87952910250f2 (patch)
tree72d079e345c66edb9e4145a230862efcce312868 /tedge_config
parentb77db397c9f877acb0da34d51203f8213bb79444 (diff)
[CIT-162] Implement Azure IoT Mapper (#242)
Implement Azure Mapper Features: - Azure Mapper takes Thin Edge JSON formatted input and coverts to Thin Edge JSON. - It adds a timestamp when `azure.mapper.timestamp` is true in the tedge config. Code changes: - Add many files in tedge_mapper crate. - Now `tedge_mapper` requires one argument, c8y or az. Lauch by `tedge_mapper az` - Add a key `azure.mapper.timestamp` in tedge config - Give a temporary solution to add `az` to tedge-mapper systemd service.
Diffstat (limited to 'tedge_config')
-rw-r--r--tedge_config/src/models/flag.rs89
-rw-r--r--tedge_config/src/models/mod.rs3
-rw-r--r--tedge_config/src/settings.rs19
-rw-r--r--tedge_config/src/tedge_config.rs21
-rw-r--r--tedge_config/src/tedge_config_dto.rs4
5 files changed, 135 insertions, 1 deletions
diff --git a/tedge_config/src/models/flag.rs b/tedge_config/src/models/flag.rs
new file mode 100644
index 00000000..debdbe36
--- /dev/null
+++ b/tedge_config/src/models/flag.rs
@@ -0,0 +1,89 @@
+use std::convert::TryFrom;
+
+/// Represents a boolean type.
+///
+/// We need this newtype in order to implement `TryFrom<String>` and `TryInto<String>`.
+/// The `config_key!` macro uses query_string() and update_string().
+/// Therefore, boolean needs to be converted from/to String.
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
+#[serde(transparent)]
+pub struct Flag(pub bool);
+
+#[derive(thiserror::Error, Debug)]
+#[error("Failed to parse flag: {input}. Supported values are: true, false")]
+pub struct InvalidFlag {
+ input: String,
+}
+
+impl TryFrom<String> for Flag {
+ type Error = InvalidFlag;
+
+ fn try_from(input: String) -> Result<Self, Self::Error> {
+ match input.as_str() {
+ "true" => Ok(Flag(true)),
+ "false" => Ok(Flag(false)),
+ _ => Err(InvalidFlag { input }),
+ }
+ }
+}
+
+impl From<Flag> for bool {
+ fn from(value: Flag) -> Self {
+ value.0
+ }
+}
+
+impl From<Flag> for String {
+ fn from(value: Flag) -> Self {
+ match value {
+ Flag(true) => "true".to_string(),
+ Flag(false) => "false".to_string(),
+ }
+ }
+}
+
+impl Flag {
+ pub fn is_set(&self) -> bool {
+ self.0
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::convert::TryInto;
+
+ #[test]
+ fn convert_string_true_to_bool_true() {
+ let input = "true".to_string();
+ let output: bool = Flag::try_from(input).unwrap().into();
+ assert_eq!(output, true);
+ }
+
+ #[test]
+ fn convert_string_false_to_bool_false() {
+ let input = "false".to_string();
+ let output: bool = Flag::try_from(input).unwrap().into();
+ assert_eq!(output, false);
+ }
+
+ #[test]
+ fn return_error_for_unexpected_string_input() {
+ let input = "unknown".to_string();
+ assert!(Flag::try_from(input).is_err());
+ }
+
+ #[test]
+ fn convert_bool_true_to_string_true() {
+ let input = true;
+ let output: String = Flag::try_into(Flag(input)).unwrap();
+ assert_eq!(output, "true");
+ }
+
+ #[test]
+ fn convert_bool_false_to_string_false() {
+ let input = false;
+ let output: String = Flag::try_into(Flag(input)).unwrap();
+ assert_eq!(output, "false");
+ }
+}
diff --git a/tedge_config/src/models/mod.rs b/tedge_config/src/models/mod.rs
index ce81e3af..9ea27a70 100644
--- a/tedge_config/src/models/mod.rs
+++ b/tedge_config/src/models/mod.rs
@@ -1,4 +1,5 @@
pub mod connect_url;
pub mod file_path;
+pub mod flag;
-pub use self::{connect_url::*, file_path::*};
+pub use self::{connect_url::*, file_path::*, flag::*};
diff --git a/tedge_config/src/settings.rs b/tedge_config/src/settings.rs
index f247cfe7..35092393 100644
--- a/tedge_config/src/settings.rs
+++ b/tedge_config/src/settings.rs
@@ -125,3 +125,22 @@ impl ConfigSetting for AzureRootCertPathSetting {
type Value = FilePath;
}
+
+///
+/// Boolean whether Azure mapper should add timestamp if timestamp is not added in the incoming payload.
+///
+/// Example: true
+///
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct AzureMapperTimestamp;
+
+impl ConfigSetting for AzureMapperTimestamp {
+ const KEY: &'static str = "azure.mapper.timestamp";
+
+ const DESCRIPTION: &'static str = concat!(
+ "Boolean whether Azure mapper should add timestamp or not. ",
+ "Example: true"
+ );
+
+ type Value = Flag;
+}
diff --git a/tedge_config/src/tedge_config.rs b/tedge_config/src/tedge_config.rs
index 29f611f5..d4d2fbbd 100644
--- a/tedge_config/src/tedge_config.rs
+++ b/tedge_config/src/tedge_config.rs
@@ -177,6 +177,27 @@ impl ConfigSettingAccessor<AzureRootCertPathSetting> for TEdgeConfig {
}
}
+impl ConfigSettingAccessor<AzureMapperTimestamp> for TEdgeConfig {
+ fn query(&self, _setting: AzureMapperTimestamp) -> ConfigSettingResult<Flag> {
+ Ok(self
+ .data
+ .azure
+ .mapper_timestamp
+ .map(Flag)
+ .unwrap_or_else(|| Flag(true)))
+ }
+
+ fn update(&mut self, _setting: AzureMapperTimestamp, value: Flag) -> ConfigSettingResult<()> {
+ self.data.azure.mapper_timestamp = Some(value.into());
+ Ok(())
+ }
+
+ fn unset(&mut self, _setting: AzureMapperTimestamp) -> ConfigSettingResult<()> {
+ self.data.azure.mapper_timestamp = None;
+ Ok(())
+ }
+}
+
impl ConfigSettingAccessor<C8yRootCertPathSetting> for TEdgeConfig {
fn query(&self, _setting: C8yRootCertPathSetting) -> ConfigSettingResult<FilePath> {
Ok(self
diff --git a/tedge_config/src/tedge_config_dto.rs b/tedge_config/src/tedge_config_dto.rs
index 6da6c74c..0d00ffbe 100644
--- a/tedge_config/src/tedge_config_dto.rs
+++ b/tedge_config/src/tedge_config_dto.rs
@@ -50,6 +50,9 @@ pub(crate) struct CumulocityConfigDto {
/// The path where Cumulocity root certificate(s) are stored.
/// The value can be a directory path as well as the path of the direct certificate file.
pub(crate) root_cert_path: Option<FilePath>,
+
+ /// Boolean whether Azure mapper adds timestamp or not.
+ pub(crate) mapper_timestamp: Option<bool>,
}
#[derive(Debug, Default, Deserialize, Serialize)]
@@ -58,4 +61,5 @@ pub(crate) struct AzureConfigDto {
pub(crate) connect: Option<String>,
pub(crate) url: Option<ConnectUrl>,
pub(crate) root_cert_path: Option<FilePath>,
+ pub(crate) mapper_timestamp: Option<bool>,
}