Skip to content

Commit f093a7e

Browse files
committed
refactor: simplify CommandRequest handling
Signed-off-by: Jan Zachmann <50990105+JanZachmann@users.noreply.github.com>
1 parent bdf9b93 commit f093a7e

File tree

14 files changed

+391
-535
lines changed

14 files changed

+391
-535
lines changed

Cargo.lock

Lines changed: 4 additions & 108 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
88
name = "omnect-device-service"
99
readme = "README.md"
1010
repository = "https://github.com/omnect/omnect-device-service.git"
11-
version = "0.41.9"
11+
version = "0.41.10"
1212

1313
[dependencies]
1414
actix-server = { version = "2.6", default-features = false }
@@ -25,12 +25,10 @@ freedesktop_entry_parser = { version = "1.3", default-features = false }
2525
futures = { version = "0.3", default-features = false }
2626
futures-util = { version = "0.3", default-features = false }
2727
glob = { version = "0.3", default-features = false }
28-
lazy_static = { version = "1.5", default-features = false }
28+
inotify = { version = "0.11", default-features = false, features = ["stream"] }
2929
log = { version = "0.4", default-features = false }
3030
log-panics = { version = "2", default-features = false }
3131
modemmanager = { git = "https://github.com/omnect/modemmanager.git", tag = "0.3.4", default-features = false, optional = true }
32-
notify = { version = "8.0", default-features = false }
33-
notify-debouncer-full = { version = "0.5", default-features = false }
3432
regex-lite = { version = "0.1", default-features = true }
3533
reqwest = { version = "0.12", default-features = false, features = [
3634
"default-tls",

src/twin/consent.rs

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
use crate::{
22
common::{from_json_file, to_json_file},
3-
twin::{Feature, feature::*},
3+
twin::feature::*,
44
};
55
use anyhow::{Context, Result, bail, ensure};
66
use azure_iot_sdk::client::IotMessage;
7+
use inotify::WatchMask;
78
use log::{info, warn};
8-
use notify_debouncer_full::{Debouncer, NoCache, notify::*};
99
use serde::{Deserialize, Serialize};
1010
use serde_json::json;
11-
use std::{collections::HashMap, env, path::Path};
11+
use std::{collections::HashMap, env, ffi::c_int, path::PathBuf};
1212
use tokio::sync::mpsc::Sender;
1313

1414
macro_rules! consent_path {
1515
() => {
16-
Path::new(&env::var("CONSENT_DIR_PATH").unwrap_or("/etc/omnect/consent".to_string()))
16+
PathBuf::from(&env::var("CONSENT_DIR_PATH").unwrap_or("/etc/omnect/consent".to_string()))
1717
};
1818
}
1919

@@ -53,9 +53,8 @@ pub struct ConsentConfig {
5353
reset_consent_on_fail: bool,
5454
}
5555

56-
#[derive(Default)]
5756
pub struct DeviceUpdateConsent {
58-
file_observer: Option<Debouncer<INotifyWatcher, NoCache>>,
57+
file_observer: HashMap<c_int, PathBuf>,
5958
tx_reported_properties: Option<Sender<serde_json::Value>>,
6059
}
6160

@@ -87,28 +86,23 @@ impl Feature for DeviceUpdateConsent {
8786
.await
8887
}
8988

90-
fn command_request_stream(&mut self) -> CommandRequestStreamResult {
91-
let (file_observer, stream) = file_modified_stream::<DeviceUpdateConsent>(vec![
92-
request_consent_path!().as_path(),
93-
history_consent_path!().as_path(),
94-
])
95-
.context("command_request_stream: cannot create file_modified_stream")?;
96-
self.file_observer = Some(file_observer);
97-
Ok(Some(stream))
98-
}
99-
10089
async fn command(&mut self, cmd: &Command) -> CommandResult {
10190
match cmd {
102-
Command::FileModified(file) => {
103-
self.report_consent(from_json_file(&file.path)?).await?;
91+
Command::WatchPath(cmd) => {
92+
self.report_consent(from_json_file(
93+
self.file_observer
94+
.get(&cmd.id)
95+
.context("cannot find file for watch id")?,
96+
)?)
97+
.await?;
10498
}
10599
Command::DesiredGeneralConsent(cmd) => {
106100
self.update_general_consent(cmd).await?;
107101
}
108102
Command::UserConsent(cmd) => {
109103
self.user_consent(cmd)?;
110104
}
111-
_ => bail!("unexpected command"),
105+
_ => bail!("unexpected command: {cmd:?}"),
112106
};
113107

114108
Ok(None)
@@ -119,6 +113,24 @@ impl DeviceUpdateConsent {
119113
const USER_CONSENT_VERSION: u8 = 1;
120114
const ID: &'static str = "device_update_consent";
121115

116+
pub async fn new() -> Result<Self> {
117+
let mut file_observer = HashMap::new();
118+
119+
for path in [request_consent_path!(), history_consent_path!()] {
120+
file_observer.insert(
121+
add_fs_watch::<Self>(&path, WatchMask::MODIFY)
122+
.await?
123+
.get_watch_descriptor_id(),
124+
path,
125+
);
126+
}
127+
128+
Ok(DeviceUpdateConsent {
129+
tx_reported_properties: None,
130+
file_observer,
131+
})
132+
}
133+
122134
fn user_consent(&self, cmd: &UserConsentCommand) -> CommandResult {
123135
info!("user consent requested: {cmd:?}");
124136

@@ -192,27 +204,29 @@ mod tests {
192204
async fn consent_files_changed_test() {
193205
let (tx_reported_properties, mut rx_reported_properties) = tokio::sync::mpsc::channel(100);
194206
let mut consent = DeviceUpdateConsent {
195-
file_observer: None,
207+
file_observer: HashMap::from([(
208+
1,
209+
PathBuf::from("testfiles/positive/test_component/user_consent.json"),
210+
)]),
196211
tx_reported_properties: Some(tx_reported_properties),
197212
};
198213

199214
assert!(
200215
consent
201-
.command(&Command::FileModified(PathCommand {
216+
.command(&Command::WatchPath(WatchPathCommand {
202217
feature_id: TypeId::of::<DeviceUpdateConsent>(),
203-
path: Path::new("my-path").to_path_buf(),
218+
id: 0,
204219
}))
205220
.await
206221
.unwrap_err()
207-
.chain()
208-
.any(|e| e.to_string().starts_with("failed to open for read: "))
222+
.to_string()
223+
.eq("cannot find file for watch id")
209224
);
210225

211226
consent
212-
.command(&Command::FileModified(PathCommand {
227+
.command(&Command::WatchPath(WatchPathCommand {
213228
feature_id: TypeId::of::<DeviceUpdateConsent>(),
214-
path: Path::new("testfiles/positive/test_component/user_consent.json")
215-
.to_path_buf(),
229+
id: 1,
216230
}))
217231
.await
218232
.unwrap();
@@ -227,7 +241,7 @@ mod tests {
227241
async fn desired_consent_test() {
228242
let (tx_reported_properties, mut rx_reported_properties) = tokio::sync::mpsc::channel(100);
229243
let mut consent = DeviceUpdateConsent {
230-
file_observer: None,
244+
file_observer: HashMap::new(),
231245
tx_reported_properties: Some(tx_reported_properties),
232246
};
233247

@@ -318,7 +332,7 @@ mod tests {
318332
async fn user_consent_test() {
319333
let (tx_reported_properties, _rx_reported_properties) = tokio::sync::mpsc::channel(100);
320334
let mut consent = DeviceUpdateConsent {
321-
file_observer: None,
335+
file_observer: HashMap::new(),
322336
tx_reported_properties: Some(tx_reported_properties),
323337
};
324338

0 commit comments

Comments
 (0)