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;
|
|
|
|
}
|
|
|
|
}
|