diff options
author | initard <solo@softwareag.com> | 2022-02-01 17:49:53 +0100 |
---|---|---|
committer | initard <solo@softwareag.com> | 2022-02-15 11:43:49 +0000 |
commit | 2411743f17e14fa6031d4940d6a0135abdc00baf (patch) | |
tree | ddc7782f8e72a4a3b4531585ec93779bfaf0c05c /crates/core/c8y_smartrest/src/topic.rs | |
parent | ae402f67527d022a3cedd60f049d73724079850a (diff) |
c8y_api lib, tedge config, mqtt/http utilities (#790)
Preparing the repo for the log request plugin. Restructuring
folders, moving code out of sm_c8y_mapper and into c8y_api,
c8y_smartrest or tedge_config.
Signed-off-by: initard <solo@softwareag.com>
Diffstat (limited to 'crates/core/c8y_smartrest/src/topic.rs')
-rw-r--r-- | crates/core/c8y_smartrest/src/topic.rs | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/crates/core/c8y_smartrest/src/topic.rs b/crates/core/c8y_smartrest/src/topic.rs new file mode 100644 index 00000000..491c7a4b --- /dev/null +++ b/crates/core/c8y_smartrest/src/topic.rs @@ -0,0 +1,160 @@ +use agent_interface::topic::ResponseTopic; +use agent_interface::TopicError; +use mqtt_channel::Topic; +use mqtt_channel::{Message, MqttError}; + +use crate::error::SMCumulocityMapperError; +use crate::smartrest_serializer::{ + CumulocitySupportedOperations, SmartRestSerializer, SmartRestSetOperationToExecuting, + SmartRestSetOperationToSuccessful, +}; + +#[derive(Debug, Clone, PartialEq)] +pub enum C8yTopic { + SmartRestRequest, + SmartRestResponse, + OperationTopic(String), +} + +impl C8yTopic { + pub fn as_str(&self) -> &str { + match self { + Self::SmartRestRequest => r#"c8y/s/ds"#, + Self::SmartRestResponse => r#"c8y/s/us"#, + Self::OperationTopic(name) => name.as_str(), + } + } + + pub fn to_topic(&self) -> Result<Topic, MqttError> { + Ok(Topic::new(self.as_str())?) + } +} + +impl TryFrom<String> for C8yTopic { + type Error = TopicError; + + fn try_from(value: String) -> Result<Self, Self::Error> { + match value.as_str() { + r#"c8y/s/ds"# => Ok(C8yTopic::SmartRestRequest), + r#"c8y/s/us"# => Ok(C8yTopic::SmartRestResponse), + topic_name => { + if topic_name[..3].contains("c8y") { + Ok(C8yTopic::OperationTopic(topic_name.to_string())) + } else { + Err(TopicError::UnknownTopic { + topic: topic_name.to_string(), + }) + } + } + } + } +} +impl TryFrom<&str> for C8yTopic { + type Error = TopicError; + + fn try_from(value: &str) -> Result<Self, Self::Error> { + Self::try_from(value.to_string()) + } +} + +impl TryFrom<Topic> for C8yTopic { + type Error = TopicError; + + fn try_from(value: Topic) -> Result<Self, Self::Error> { + value.name.try_into() + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum MapperSubscribeTopic { + C8yTopic(C8yTopic), + ResponseTopic(ResponseTopic), +} + +impl TryFrom<String> for MapperSubscribeTopic { + type Error = TopicError; + fn try_from(value: String) -> Result<Self, Self::Error> { + match ResponseTopic::try_from(value.clone()) { + Ok(response_topic) => Ok(MapperSubscribeTopic::ResponseTopic(response_topic)), + Err(_) => match C8yTopic::try_from(value) { + Ok(smart_rest_request) => Ok(MapperSubscribeTopic::C8yTopic(smart_rest_request)), + Err(err) => Err(err), + }, + } + } +} + +impl TryFrom<&str> for MapperSubscribeTopic { + type Error = TopicError; + + fn try_from(value: &str) -> Result<Self, Self::Error> { + Self::try_from(value.to_string()) + } +} + +impl TryFrom<Topic> for MapperSubscribeTopic { + type Error = TopicError; + + fn try_from(value: Topic) -> Result<Self, Self::Error> { + value.name.try_into() + } +} + +/// returns a c8y message specifying to set log status to executing. +/// +/// example message: '501,c8y_LogfileRequest' +pub async fn get_log_file_request_executing() -> Result<Message, SMCumulocityMapperError> { + let topic = C8yTopic::SmartRestResponse.to_topic()?; + let smartrest_set_operation_status = + SmartRestSetOperationToExecuting::new(CumulocitySupportedOperations::C8yLogFileRequest) + .to_smartrest()?; + Ok(Message::new(&topic, smartrest_set_operation_status)) +} + +/// returns a c8y message specifying to set log status to successful. +/// +/// example message: '503,c8y_LogfileRequest,https://{c8y.url}/etc...' +pub async fn get_log_file_request_done_message( + binary_upload_event_url: &str, +) -> Result<Message, SMCumulocityMapperError> { + let topic = C8yTopic::SmartRestResponse.to_topic()?; + let smartrest_set_operation_status = + SmartRestSetOperationToSuccessful::new(CumulocitySupportedOperations::C8yLogFileRequest) + .with_response_parameter(binary_upload_event_url) + .to_smartrest()?; + + Ok(Message::new(&topic, smartrest_set_operation_status)) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::convert::TryInto; + + #[test] + fn convert_c8y_topic_to_str() { + assert_eq!(C8yTopic::SmartRestRequest.as_str(), "c8y/s/ds"); + assert_eq!(C8yTopic::SmartRestResponse.as_str(), "c8y/s/us"); + } + + #[test] + fn convert_str_into_c8y_topic() { + let c8y_req: C8yTopic = "c8y/s/ds".try_into().unwrap(); + assert_eq!(c8y_req, C8yTopic::SmartRestRequest); + let c8y_resp: C8yTopic = "c8y/s/us".try_into().unwrap(); + assert_eq!(c8y_resp, C8yTopic::SmartRestResponse); + let error: Result<C8yTopic, TopicError> = "test".try_into(); + assert!(error.is_err()); + } + + #[test] + fn convert_topic_into_c8y_topic() { + let c8y_req: C8yTopic = Topic::new("c8y/s/ds").unwrap().try_into().unwrap(); + assert_eq!(c8y_req, C8yTopic::SmartRestRequest); + + let c8y_resp: C8yTopic = Topic::new("c8y/s/us").unwrap().try_into().unwrap(); + assert_eq!(c8y_resp, C8yTopic::SmartRestResponse); + let error: Result<C8yTopic, TopicError> = Topic::new("test").unwrap().try_into(); + assert!(error.is_err()); + } +} |