@@ -12,13 +12,17 @@ use tedge_api::entity_store::EntityTwinMessage;
12
12
use tedge_api:: entity_store:: EntityUpdateMessage ;
13
13
use tedge_api:: entity_store:: ListFilters ;
14
14
use tedge_api:: mqtt_topics:: Channel ;
15
+ use tedge_api:: mqtt_topics:: ChannelFilter ;
16
+ use tedge_api:: mqtt_topics:: EntityFilter ;
15
17
use tedge_api:: mqtt_topics:: EntityTopicId ;
16
18
use tedge_api:: mqtt_topics:: MqttSchema ;
17
19
use tedge_api:: pending_entity_store:: RegisteredEntityData ;
18
20
use tedge_api:: EntityStore ;
21
+ use tedge_mqtt_ext:: MqttConnector ;
19
22
use tedge_mqtt_ext:: MqttMessage ;
20
- use tedge_mqtt_ext:: QoS ;
21
23
use tedge_mqtt_ext:: TopicFilter ;
24
+ use tokio:: time:: timeout;
25
+ use tokio:: time:: Duration ;
22
26
use tracing:: error;
23
27
24
28
#[ derive( Debug ) ]
@@ -52,6 +56,7 @@ pub enum EntityStoreResponse {
52
56
pub struct EntityStoreServer {
53
57
entity_store : EntityStore ,
54
58
mqtt_schema : MqttSchema ,
59
+ mqtt_connector : Box < dyn MqttConnector > ,
55
60
mqtt_publisher : LoggingSender < MqttMessage > ,
56
61
entity_auto_register : bool ,
57
62
}
@@ -60,6 +65,7 @@ impl EntityStoreServer {
60
65
pub fn new (
61
66
entity_store : EntityStore ,
62
67
mqtt_schema : MqttSchema ,
68
+ mqtt_connector : Box < dyn MqttConnector > ,
63
69
mqtt_actor : & mut impl MessageSink < MqttMessage > ,
64
70
entity_auto_register : bool ,
65
71
) -> Self {
@@ -68,6 +74,7 @@ impl EntityStoreServer {
68
74
Self {
69
75
entity_store,
70
76
mqtt_schema,
77
+ mqtt_connector,
71
78
mqtt_publisher,
72
79
entity_auto_register,
73
80
}
@@ -306,24 +313,56 @@ impl EntityStoreServer {
306
313
307
314
async fn deregister_entity ( & mut self , topic_id : & EntityTopicId ) -> Vec < EntityMetadata > {
308
315
let deleted = self . entity_store . deregister_entity ( topic_id) ;
309
- for entity in deleted. iter ( ) . rev ( ) {
310
- for twin_key in entity. twin_data . keys ( ) {
311
- let topic = self . mqtt_schema . topic_for (
312
- & entity. topic_id ,
313
- & Channel :: EntityTwinData {
314
- fragment_key : twin_key. to_string ( ) ,
315
- } ,
316
- ) ;
317
- let clear_twin_msg = MqttMessage :: new ( & topic, "" ) . with_retain ( ) ;
318
-
319
- self . publish_message ( clear_twin_msg) . await ;
316
+
317
+ let mut topics = TopicFilter :: empty ( ) ;
318
+ for entity in deleted. iter ( ) {
319
+ for channel_filter in [
320
+ ChannelFilter :: MeasurementMetadata ,
321
+ ChannelFilter :: EventMetadata ,
322
+ ChannelFilter :: AlarmMetadata ,
323
+ ChannelFilter :: Alarm ,
324
+ ChannelFilter :: EntityTwinData ,
325
+ ChannelFilter :: AnyCommand ,
326
+ ChannelFilter :: AnyCommandMetadata ,
327
+ ] {
328
+ let topic = self
329
+ . mqtt_schema
330
+ . topics ( EntityFilter :: Entity ( & entity. topic_id ) , channel_filter) ;
331
+ topics. add_all ( topic) ;
332
+ }
333
+ }
334
+
335
+ // A single connection to retrieve all retained metadata messages for all deleted entities
336
+ match self . mqtt_connector . connect ( topics) . await {
337
+ Ok ( mut connection) => {
338
+ while let Ok ( Some ( message) ) =
339
+ timeout ( Duration :: from_secs ( 1 ) , connection. next_message ( ) ) . await
340
+ {
341
+ if message. retain && !message. payload_bytes ( ) . is_empty ( ) {
342
+ let clear_msg = MqttMessage :: new ( & message. topic , "" ) . with_retain ( ) ;
343
+ if let Err ( err) = self . mqtt_publisher . send ( clear_msg) . await {
344
+ error ! (
345
+ "Failed to clear retained message on topic {} while de-registering {} due to: {err}" ,
346
+ topic_id,
347
+ message. topic
348
+ ) ;
349
+ }
350
+ }
351
+ }
352
+
353
+ connection. disconnect ( ) . await ;
354
+ }
355
+ Err ( err) => {
356
+ error ! ( "Failed to create MQTT connection for clearing entity data: {err}" ) ;
320
357
}
358
+ }
359
+
360
+ // Clear the entity metadata of all deleted entities bottom up
361
+ for entity in deleted. iter ( ) . rev ( ) {
321
362
let topic = self
322
363
. mqtt_schema
323
364
. topic_for ( & entity. topic_id , & Channel :: EntityMetadata ) ;
324
- let clear_entity_msg = MqttMessage :: new ( & topic, "" )
325
- . with_retain ( )
326
- . with_qos ( QoS :: AtLeastOnce ) ;
365
+ let clear_entity_msg = MqttMessage :: new ( & topic, "" ) . with_retain ( ) ;
327
366
328
367
self . publish_message ( clear_entity_msg) . await ;
329
368
}
0 commit comments