summaryrefslogtreecommitdiffstats
path: root/crates/core/c8y_smartrest/src/topic.rs
diff options
context:
space:
mode:
authorinitard <solo@softwareag.com>2022-02-01 17:49:53 +0100
committerinitard <solo@softwareag.com>2022-02-15 11:43:49 +0000
commit2411743f17e14fa6031d4940d6a0135abdc00baf (patch)
treeddc7782f8e72a4a3b4531585ec93779bfaf0c05c /crates/core/c8y_smartrest/src/topic.rs
parentae402f67527d022a3cedd60f049d73724079850a (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.rs160
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());
+ }
+}