public_appservice/
ping.rs1use axum::{Json, extract::State, response::IntoResponse};
2
3use std::sync::Arc;
4use tokio::sync::RwLock;
5use uuid::Uuid;
6
7use serde::Deserialize;
8use serde_json::json;
9
10use crate::AppState;
11use crate::error::AppserviceError;
12
13#[derive(Debug, Clone)]
14pub struct TransactionStore {
15 current_id: Arc<RwLock<Option<String>>>,
16}
17
18impl Default for TransactionStore {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23
24impl TransactionStore {
25 pub fn new() -> Self {
26 Self {
27 current_id: Arc::new(RwLock::new(None)),
28 }
29 }
30
31 pub async fn generate_transaction_id(&self) -> String {
32 let transaction_id = Uuid::new_v4().to_string();
33 let mut store = self.current_id.write().await;
34 *store = Some(transaction_id.clone());
35 transaction_id
36 }
37
38 pub async fn verify_and_remove_transaction(&self, transaction_id: &str) -> bool {
39 let mut store = self.current_id.write().await;
40 if let Some(stored_id) = store.as_ref() {
41 if stored_id == transaction_id {
42 *store = None;
43 return true;
44 }
45 }
46 false
47 }
48}
49
50#[derive(Debug, Clone, Deserialize)]
51pub struct PingRequest {
52 pub transaction_id: String,
53}
54
55pub async fn ping(
56 State(state): State<Arc<AppState>>,
57 Json(payload): Json<PingRequest>,
58) -> Result<impl IntoResponse, AppserviceError> {
59 let txn_id = payload.transaction_id.clone();
60
61 if !state
62 .transaction_store
63 .verify_and_remove_transaction(&txn_id)
64 .await
65 {
66 tracing::info!("Transaction ID does not match: {}", txn_id);
67 }
68
69 Ok(Json(json!({})))
70}