gbserver/gb-messaging/src/kafka.rs

115 lines
2.9 KiB
Rust
Raw Normal View History

2024-12-23 00:20:59 -03:00
use gb_core::{Result, Error};
use rdkafka::producer::{FutureProducer, FutureRecord};
use rdkafka::consumer::{StreamConsumer, Consumer};
use rdkafka::ClientConfig;
2024-12-22 20:56:52 -03:00
use std::time::Duration;
2024-12-23 00:20:59 -03:00
use serde::Serialize;
2024-12-25 16:25:09 -03:00
use super::kafka;
2024-12-23 00:20:59 -03:00
pub struct Kafka {
2024-12-25 16:25:09 -03:00
broker_address: String,
group_id: String,
2024-12-22 20:56:52 -03:00
producer: FutureProducer,
consumer: StreamConsumer,
}
2024-12-23 00:20:59 -03:00
impl Kafka {
2024-12-25 16:25:09 -03:00
pub async fn new(broker_address: &str, group_id: &str) -> Result<Self> {
2024-12-23 00:20:59 -03:00
let producer = ClientConfig::new()
2024-12-25 16:25:09 -03:00
.set("bootstrap.servers", broker_address)
2024-12-22 20:56:52 -03:00
.create()
2024-12-23 00:20:59 -03:00
.map_err(|e| Error::kafka(format!("Failed to create producer: {}", e)))?;
2024-12-22 20:56:52 -03:00
2024-12-25 16:25:09 -03:00
let consumer = ClientConfig::new()
.set("bootstrap.servers", broker_address)
.set("group.id", group_id)
2024-12-22 20:56:52 -03:00
.create()
2024-12-23 00:20:59 -03:00
.map_err(|e| Error::kafka(format!("Failed to create consumer: {}", e)))?;
2024-12-22 20:56:52 -03:00
Ok(Self {
2024-12-25 16:25:09 -03:00
broker_address: broker_address.to_string(),
group_id: group_id.to_string(),
2024-12-22 20:56:52 -03:00
producer,
consumer,
})
}
2024-12-23 00:20:59 -03:00
pub async fn publish<T: Serialize>(&self, topic: &str, message: &T) -> Result<()> {
let payload = serde_json::to_string(message)
.map_err(|e| Error::internal(format!("Serialization error: {}", e)))?;
2024-12-22 20:56:52 -03:00
self.producer
.send(
FutureRecord::to(topic)
2024-12-23 00:20:59 -03:00
.payload(payload.as_bytes())
.key(""),
Duration::from_secs(0),
2024-12-22 20:56:52 -03:00
)
.await
2024-12-23 00:20:59 -03:00
.map_err(|(e, _)| Error::kafka(format!("Failed to send message: {}", e)))?;
2024-12-22 20:56:52 -03:00
Ok(())
}
2024-12-23 00:20:59 -03:00
pub async fn subscribe(&self, topic: &str) -> Result<()> {
2024-12-22 20:56:52 -03:00
self.consumer
2024-12-23 00:20:59 -03:00
.subscribe(&[topic])
.map_err(|e| Error::kafka(format!("Failed to subscribe: {}", e)))?;
2024-12-22 20:56:52 -03:00
2024-12-23 00:20:59 -03:00
Ok(())
2024-12-22 20:56:52 -03:00
}
}
2024-12-25 16:25:09 -03:00
2024-12-22 20:56:52 -03:00
#[cfg(test)]
mod tests {
use super::*;
use rstest::*;
2024-12-25 16:25:09 -03:00
use tokio;
2024-12-22 20:56:52 -03:00
use serde::{Deserialize, Serialize};
2024-12-23 00:20:59 -03:00
use uuid::Uuid;
2024-12-25 16:25:09 -03:00
use std::future::Future;
use tokio::runtime::Runtime;
2024-12-22 20:56:52 -03:00
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct TestMessage {
id: Uuid,
content: String,
}
#[fixture]
fn test_message() -> TestMessage {
TestMessage {
id: Uuid::new_v4(),
content: "test message".to_string(),
}
}
2024-12-25 16:25:09 -03:00
#[fixture]
async fn kafka() -> Kafka {
Kafka::new(
"localhost:9092",
"test-group",
).await.unwrap()
}
2024-12-22 20:56:52 -03:00
#[rstest]
#[tokio::test]
2024-12-25 16:25:09 -03:00
async fn test_publish_subscribe(
#[future] kafka: Kafka,
test_message: TestMessage
) {
2024-12-22 20:56:52 -03:00
let topic = "test-topic";
2024-12-25 16:25:09 -03:00
let kafka = kafka.await;
kafka.publish(topic, &test_message)
2024-12-22 20:56:52 -03:00
.await
.unwrap();
2024-12-25 16:25:09 -03:00
kafka.subscribe(topic)
2024-12-23 00:20:59 -03:00
.await
.unwrap();
2024-12-22 20:56:52 -03:00
tokio::time::sleep(Duration::from_secs(1)).await;
}
}