use std::str::FromStr;
use ahash::{HashMap, HashMapExt};
use rdkafka::{
message::{BorrowedMessage, Header, Headers, OwnedHeaders},
Message,
};
use serde::de::DeserializeOwned;
use talos_certifier::{core::MessageVariant, errors::CommonError};
pub fn get_message_headers(message: &BorrowedMessage) -> Option<HashMap<String, String>> {
if let Some(headers) = message.headers() {
let headers = (0..headers.count()).fold(HashMap::<String, String>::new(), |mut acc, i| {
if let (k, Some(v)) = (headers.get(i).key, headers.get(i).value) {
acc.insert(k.to_owned(), String::from_utf8_lossy(v).into_owned());
}
acc
});
if headers.is_empty() {
return None;
} else {
return Some(headers);
}
}
None
}
pub fn build_kafka_headers(headers: HashMap<String, String>) -> OwnedHeaders {
let owned_headers = OwnedHeaders::new();
let owned_headers = headers.iter().fold(owned_headers, |acc, x| {
let header = Header { key: x.0, value: Some(x.1) };
acc.insert(header)
});
owned_headers
}
pub fn parse_kafka_payload<T: DeserializeOwned>(message: &[u8]) -> Result<T, CommonError> {
serde_json::from_slice::<T>(message).map_err(|err| CommonError::ParseError {
data: String::from_utf8_lossy(message).into_owned(),
reason: err.to_string(),
})
}
pub fn parse_message_variant(message_type: &String) -> Result<MessageVariant, CommonError> {
MessageVariant::from_str(message_type).map_err(|e| CommonError::ParseError {
reason: e.to_string(),
data: message_type.to_string(),
})
}
#[cfg(test)]
mod tests {
use ahash::{HashMap, HashMapExt};
use rdkafka::message::Headers;
use serde::Deserialize;
use talos_certifier::{core::MessageVariant, errors::CommonError};
use crate::kafka::utils::parse_kafka_payload;
use super::{build_kafka_headers, parse_message_variant};
#[test]
fn test_parse_kafka_payload_successfully() {
#[derive(Deserialize)]
struct User {
name: String,
age: u32,
}
let json_user_data_as_str = r#"
{
"name": "John Doe",
"age": 43
}"#;
let json_user_data_as_u8array = json_user_data_as_str.as_bytes();
let parse_result = parse_kafka_payload::<User>(json_user_data_as_u8array).unwrap();
assert_eq!(parse_result.name, "John Doe".to_owned());
assert_eq!(parse_result.age, 43);
}
#[test]
fn test_parse_kafka_payload_error_parsing() {
#[derive(Deserialize, Debug)]
struct User {
_name: String,
_age: u32,
}
let json_user_data_as_str = "Hello World";
let json_user_data_as_u8array = json_user_data_as_str.as_bytes();
let parse_error = parse_kafka_payload::<User>(json_user_data_as_u8array).unwrap_err();
assert!(matches!(parse_error, CommonError::ParseError { .. }));
}
#[test]
fn test_parse_message_variant_successfully() {
let parse_candidate_variant = parse_message_variant(&"Candidate".to_string()).unwrap();
assert_eq!(parse_candidate_variant, MessageVariant::Candidate);
let parse_decision_variant = parse_message_variant(&"Decision".to_string()).unwrap();
assert_eq!(parse_decision_variant, MessageVariant::Decision);
}
#[test]
fn test_parse_message_variant_error() {
let parse_error = parse_message_variant(&"Error type".to_string()).unwrap_err();
assert!(matches!(parse_error, CommonError::ParseError { .. }));
}
#[test]
fn test_building_kafka_headers_correctly() {
let mut header_hashmap = HashMap::new();
header_hashmap.insert("header1".to_owned(), "value1".to_owned());
let owned_headers_result = build_kafka_headers(header_hashmap.clone());
assert_eq!(owned_headers_result.get(0).key, "header1".to_owned());
assert_eq!(build_kafka_headers(header_hashmap.clone()).count(), 1);
}
}