2024-12-22 20:56:52 -03:00
|
|
|
use axum::{
|
|
|
|
routing::{get, post},
|
|
|
|
Router,
|
2024-12-23 00:54:50 -03:00
|
|
|
extract::{
|
2024-12-24 09:59:55 -03:00
|
|
|
ws::WebSocket,
|
2024-12-23 00:54:50 -03:00
|
|
|
Path, State, WebSocketUpgrade,
|
|
|
|
},
|
2024-12-22 20:56:52 -03:00
|
|
|
response::IntoResponse,
|
|
|
|
Json,
|
|
|
|
};
|
|
|
|
use gb_core::{Result, Error, models::*};
|
2024-12-24 09:59:55 -03:00
|
|
|
use gb_messaging::{MessageProcessor, models::MessageEnvelope};
|
2024-12-24 10:09:14 -03:00
|
|
|
use std::{sync::Arc, collections::HashMap};
|
2024-12-22 20:56:52 -03:00
|
|
|
use tokio::sync::Mutex;
|
|
|
|
use tracing::{instrument, error};
|
|
|
|
use uuid::Uuid;
|
2024-12-23 00:54:50 -03:00
|
|
|
use futures_util::StreamExt;
|
2024-12-22 20:56:52 -03:00
|
|
|
|
2024-12-24 09:22:30 -03:00
|
|
|
pub struct ApiState {
|
|
|
|
pub message_processor: Mutex<MessageProcessor>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn create_router(message_processor: MessageProcessor) -> Router {
|
|
|
|
let state = Arc::new(ApiState {
|
|
|
|
message_processor: Mutex::new(message_processor),
|
|
|
|
});
|
|
|
|
|
|
|
|
Router::new()
|
|
|
|
.route("/health", get(|| async { "OK" }))
|
|
|
|
.route("/messages", post(send_message))
|
|
|
|
.route("/messages/:id", get(get_message))
|
|
|
|
.route("/rooms", post(create_room))
|
|
|
|
.route("/rooms/:id", get(get_room))
|
|
|
|
.route("/rooms/:id/join", post(join_room))
|
|
|
|
.route("/ws", get(websocket_handler))
|
|
|
|
.with_state(state)
|
|
|
|
}
|
|
|
|
|
2024-12-23 17:36:12 -03:00
|
|
|
async fn handle_ws_connection(
|
|
|
|
ws: WebSocket,
|
2024-12-24 09:59:55 -03:00
|
|
|
state: Arc<ApiState>,
|
|
|
|
) -> Result<()> {
|
|
|
|
let (_sender, mut receiver) = ws.split();
|
|
|
|
|
|
|
|
while let Some(Ok(msg)) = receiver.next().await {
|
|
|
|
if let Ok(text) = msg.to_text() {
|
2024-12-25 16:25:09 -03:00
|
|
|
if let Ok(_envelope) = serde_json::from_str::<MessageEnvelope>(text) {
|
2024-12-24 09:59:55 -03:00
|
|
|
let mut processor = state.message_processor.lock().await;
|
2024-12-24 13:05:54 -03:00
|
|
|
if let Err(e) = processor.process_messages().await {
|
2024-12-24 09:59:55 -03:00
|
|
|
error!("Failed to process message: {}", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
2024-12-22 20:56:52 -03:00
|
|
|
}
|
|
|
|
|
2024-12-24 10:09:14 -03:00
|
|
|
#[instrument(skip_all)]
|
2024-12-22 20:56:52 -03:00
|
|
|
async fn websocket_handler(
|
|
|
|
State(state): State<Arc<ApiState>>,
|
|
|
|
ws: WebSocketUpgrade,
|
|
|
|
) -> impl IntoResponse {
|
2024-12-24 10:09:14 -03:00
|
|
|
ws.on_upgrade(move |socket| async move {
|
2024-12-24 09:59:55 -03:00
|
|
|
let _ = handle_ws_connection(socket, state).await;
|
2024-12-22 20:56:52 -03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-12-24 10:09:14 -03:00
|
|
|
#[instrument(skip_all)]
|
2024-12-22 20:56:52 -03:00
|
|
|
async fn send_message(
|
|
|
|
State(state): State<Arc<ApiState>>,
|
|
|
|
Json(message): Json<Message>,
|
|
|
|
) -> Result<Json<MessageId>> {
|
|
|
|
let envelope = MessageEnvelope {
|
|
|
|
id: Uuid::new_v4(),
|
|
|
|
message,
|
2024-12-24 10:09:14 -03:00
|
|
|
metadata: HashMap::new(),
|
2024-12-22 20:56:52 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
let mut processor = state.message_processor.lock().await;
|
2024-12-24 13:05:54 -03:00
|
|
|
processor.process_messages().await
|
2024-12-24 09:59:55 -03:00
|
|
|
.map_err(|e| Error::internal(format!("Failed to process message: {}", e)))?;
|
2024-12-22 20:56:52 -03:00
|
|
|
|
|
|
|
Ok(Json(MessageId(envelope.id)))
|
|
|
|
}
|
|
|
|
|
2024-12-24 10:09:14 -03:00
|
|
|
#[instrument(skip_all)]
|
2024-12-22 20:56:52 -03:00
|
|
|
async fn get_message(
|
2024-12-24 09:59:55 -03:00
|
|
|
State(_state): State<Arc<ApiState>>,
|
2024-12-24 10:09:14 -03:00
|
|
|
Path(_id): Path<Uuid>,
|
2024-12-22 20:56:52 -03:00
|
|
|
) -> Result<Json<Message>> {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
2024-12-24 10:09:14 -03:00
|
|
|
#[instrument(skip_all)]
|
2024-12-22 20:56:52 -03:00
|
|
|
async fn create_room(
|
2024-12-24 09:22:30 -03:00
|
|
|
State(_state): State<Arc<ApiState>>,
|
|
|
|
Json(_config): Json<RoomConfig>,
|
2024-12-22 20:56:52 -03:00
|
|
|
) -> Result<Json<Room>> {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
2024-12-24 10:09:14 -03:00
|
|
|
#[instrument(skip_all)]
|
2024-12-22 20:56:52 -03:00
|
|
|
async fn get_room(
|
2024-12-24 09:59:55 -03:00
|
|
|
State(_state): State<Arc<ApiState>>,
|
2024-12-24 10:09:14 -03:00
|
|
|
Path(_id): Path<Uuid>,
|
2024-12-22 20:56:52 -03:00
|
|
|
) -> Result<Json<Room>> {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
2024-12-24 10:09:14 -03:00
|
|
|
#[instrument(skip_all)]
|
2024-12-22 20:56:52 -03:00
|
|
|
async fn join_room(
|
2024-12-24 09:59:55 -03:00
|
|
|
State(_state): State<Arc<ApiState>>,
|
2024-12-24 10:09:14 -03:00
|
|
|
Path(_id): Path<Uuid>,
|
|
|
|
Json(_user_id): Json<Uuid>,
|
2024-12-22 20:56:52 -03:00
|
|
|
) -> Result<Json<Connection>> {
|
|
|
|
todo!()
|
2024-12-24 13:05:54 -03:00
|
|
|
}
|