diff --git a/crates/extensions/tedge_config_manager/src/actor.rs b/crates/extensions/tedge_config_manager/src/actor.rs index 6ba2749a092..0e5973cd0ef 100644 --- a/crates/extensions/tedge_config_manager/src/actor.rs +++ b/crates/extensions/tedge_config_manager/src/actor.rs @@ -196,7 +196,10 @@ impl ConfigManagerActor { topic: &Topic, mut request: ConfigSnapshotCmdPayload, ) -> Result<(), ChannelError> { - match self.execute_config_snapshot_request(topic, &request).await { + match self + .execute_config_snapshot_request(topic, &mut request) + .await + { Ok(_) => { self.pending_operations .insert(topic.name.clone(), ConfigOperation::Snapshot(request)); @@ -217,15 +220,21 @@ impl ConfigManagerActor { async fn execute_config_snapshot_request( &mut self, topic: &Topic, - request: &ConfigSnapshotCmdPayload, + request: &mut ConfigSnapshotCmdPayload, ) -> Result<(), ConfigManagementError> { let file_entry = self .plugin_config .get_file_entry_from_type(&request.config_type)?; - let Some(tedge_url) = &request.tedge_url else { - debug!("tedge_url not present in config snapshot payload, ignoring"); - return Ok(()); + let tedge_url = match &request.tedge_url { + Some(tedge_url) => tedge_url, + None => { + request.executing(Some( + self.create_tedge_url_for_config_operation(topic, &request.config_type)?, + )); + // Safe to unwrap because we've just created the url + request.tedge_url.as_ref().unwrap() + } }; let upload_request = UploadRequest::new(tedge_url, Utf8Path::new(&file_entry.path)); diff --git a/crates/extensions/tedge_config_manager/src/tests.rs b/crates/extensions/tedge_config_manager/src/tests.rs index d75dbb62755..51fbb147162 100644 --- a/crates/extensions/tedge_config_manager/src/tests.rs +++ b/crates/extensions/tedge_config_manager/src/tests.rs @@ -497,3 +497,53 @@ async fn send_incorrect_payload() -> Result<(), anyhow::Error> { Ok(()) } + +#[tokio::test] +async fn receive_executing_snapshot_request_without_tedge_url() -> Result<(), anyhow::Error> { + let tempdir = prepare()?; + let (mut mqtt, _fs, _downloader, mut uploader) = + spawn_config_manager_actor(tempdir.path()).await; + + let config_topic = Topic::new_unchecked("te/device/main///cmd/config_snapshot/1234"); + + // Let's ignore the reload messages sent on start + mqtt.skip(2).await; + + // Received executing snapshot request + let executing_request = r#" + { + "status": "executing", + "type": "type_two" + }"#; + + mqtt.send(MqttMessage::new(&config_topic, executing_request).with_retain()) + .await?; + + // Assert config upload request. + let (topic, upload_request) = uploader.recv().await.unwrap(); + + assert_eq!(Topic::new_unchecked(&topic), config_topic); + + assert_eq!( + upload_request.url, + "http://127.0.0.1:3000/tedge/file-transfer/main/config_snapshot/type_two-1234" + ); + assert_eq!(upload_request.file_path, tempdir.path().join("file_b")); + + assert_eq!(upload_request.auth, None); + + // Simulate upload file completion + let upload_response = UploadResponse::new(&upload_request.url, upload_request.file_path); + uploader.send((topic, Ok(upload_response))).await?; + + // Finally, the config manager notifies that request was successfully processed + assert_eq!( + mqtt.recv().await, + Some(MqttMessage::new( + &config_topic, + format!(r#"{{"status":"successful","tedgeUrl":"http://127.0.0.1:3000/tedge/file-transfer/main/config_snapshot/type_two-1234","type":"type_two","path":{:?}}}"#, tempdir.path().join("file_b")) + ).with_retain()) + ); + + Ok(()) +}