mockforge_core/consumer_contracts/
registry.rs

1//! Consumer registry for tracking API consumers
2//!
3//! This module provides functionality for registering and querying consumers.
4
5use crate::consumer_contracts::types::{Consumer, ConsumerIdentifier};
6use std::collections::HashMap;
7use std::sync::Arc;
8use tokio::sync::RwLock;
9use uuid::Uuid;
10
11/// Registry for tracking consumers
12#[derive(Debug, Clone)]
13pub struct ConsumerRegistry {
14    /// Consumers indexed by ID
15    consumers: Arc<RwLock<HashMap<String, Consumer>>>,
16    /// Index by identifier for fast lookup
17    identifier_index: Arc<RwLock<HashMap<ConsumerIdentifier, String>>>,
18}
19
20impl ConsumerRegistry {
21    /// Create a new consumer registry
22    pub fn new() -> Self {
23        Self {
24            consumers: Arc::new(RwLock::new(HashMap::new())),
25            identifier_index: Arc::new(RwLock::new(HashMap::new())),
26        }
27    }
28
29    /// Register a consumer
30    pub async fn register(&self, consumer: Consumer) {
31        let id = consumer.id.clone();
32        let identifier = consumer.identifier.clone();
33
34        // Store consumer
35        {
36            let mut consumers = self.consumers.write().await;
37            consumers.insert(id.clone(), consumer);
38        }
39
40        // Update identifier index
41        {
42            let mut index = self.identifier_index.write().await;
43            index.insert(identifier, id);
44        }
45    }
46
47    /// Get consumer by ID
48    pub async fn get_by_id(&self, id: &str) -> Option<Consumer> {
49        let consumers = self.consumers.read().await;
50        consumers.get(id).cloned()
51    }
52
53    /// Get consumer by identifier
54    pub async fn get_by_identifier(&self, identifier: &ConsumerIdentifier) -> Option<Consumer> {
55        let consumer_id = {
56            let index = self.identifier_index.read().await;
57            index.get(identifier).cloned()
58        };
59
60        if let Some(consumer_id) = consumer_id {
61            self.get_by_id(&consumer_id).await
62        } else {
63            None
64        }
65    }
66
67    /// List all consumers
68    pub async fn list_all(&self) -> Vec<Consumer> {
69        let consumers = self.consumers.read().await;
70        consumers.values().cloned().collect()
71    }
72
73    /// Remove a consumer
74    pub async fn remove(&self, id: &str) -> Option<Consumer> {
75        let consumer = {
76            let mut consumers = self.consumers.write().await;
77            consumers.remove(id)
78        };
79
80        if let Some(ref consumer) = consumer {
81            let mut index = self.identifier_index.write().await;
82            index.remove(&consumer.identifier);
83        }
84
85        consumer
86    }
87
88    /// Create or get consumer by identifier
89    pub async fn get_or_create(
90        &self,
91        identifier: ConsumerIdentifier,
92        name: String,
93        workspace_id: Option<String>,
94    ) -> Consumer {
95        // Try to get existing consumer
96        if let Some(consumer) = self.get_by_identifier(&identifier).await {
97            return consumer;
98        }
99
100        // Create new consumer
101        let id = Uuid::new_v4().to_string();
102        let consumer = Consumer::new(id, identifier, name, workspace_id);
103        self.register(consumer.clone()).await;
104        consumer
105    }
106}
107
108impl Default for ConsumerRegistry {
109    fn default() -> Self {
110        Self::new()
111    }
112}