cal_redis/cache/
jambonz.rs

1// File: cal-redis/src/cache/jambonz.rs
2
3use super::CallableCache;
4use crate::common::{deserialize_from_json, serialize_to_json};
5use crate::constants::JAMBONZ_KEY;
6use cal_core::JambonzEntry;
7use redis::{AsyncCommands, RedisError};
8use std::sync::Arc;
9
10impl CallableCache {
11    /// Inserts a Jambonz entry into Redis.
12    ///
13    /// # Arguments
14    /// * `entry` - The Jambonz entry to insert
15    ///
16    /// # Returns
17    /// * `Result<(), RedisError>` - Ok if successful, or a Redis error
18    pub async fn insert_jambonz_entry(&self, entry: JambonzEntry) -> Result<(), RedisError> {
19        println!(
20            "[CallableCache::insert_jambonz_entry] Inserting Jambonz entry for realm: {}",
21            entry.sip_realm
22        );
23
24        let mut con = self.redis_connection();
25        let value = serialize_to_json(&entry)?;
26
27        // Store in hash with sip_realm as field
28        con.hset(JAMBONZ_KEY, &entry.sip_realm, value).await?;
29
30        println!("[CallableCache::insert_jambonz_entry] Successfully inserted Jambonz entry");
31        Ok(())
32    }
33
34    /// Retrieves a Jambonz entry by SIP realm.
35    ///
36    /// # Arguments
37    /// * `sip_realm` - The SIP realm (e.g., insurancesearch.connect.callable.io)
38    ///
39    /// # Returns
40    /// * `Result<Option<Arc<JambonzEntry>>, RedisError>` - The entry if found, None if not found, or a Redis error
41    pub async fn get_jambonz_entry(
42        &self,
43        sip_realm: &str,
44    ) -> Result<Option<Arc<JambonzEntry>>, RedisError> {
45        println!(
46            "[CallableCache::get_jambonz_entry] Getting Jambonz entry for realm: {}",
47            sip_realm
48        );
49
50        let con = self.redis_connection();
51        let value: Option<String> = con.clone().hget(JAMBONZ_KEY, sip_realm).await?;
52
53        match value {
54            Some(json_str) => {
55                let entry: JambonzEntry = deserialize_from_json(&json_str)?;
56                println!("[CallableCache::get_jambonz_entry] Found Jambonz entry");
57                Ok(Some(Arc::new(entry)))
58            }
59            None => {
60                println!("[CallableCache::get_jambonz_entry] Jambonz entry not found");
61                Ok(None)
62            }
63        }
64    }
65
66    /// Retrieves all Jambonz entries.
67    ///
68    /// # Returns
69    /// * `Result<Vec<Arc<JambonzEntry>>, RedisError>` - List of all entries
70    pub async fn get_all_jambonz_entries(&self) -> Result<Vec<Arc<JambonzEntry>>, RedisError> {
71        println!("[CallableCache::get_all_jambonz_entries] Getting all Jambonz entries");
72
73        let con = self.redis_connection();
74        let values: Vec<String> = con.clone().hvals(JAMBONZ_KEY).await?;
75
76        let mut entries = Vec::new();
77        for json_str in values {
78            match deserialize_from_json::<JambonzEntry>(&json_str) {
79                Ok(entry) => {
80                    entries.push(Arc::new(entry));
81                }
82                Err(e) => {
83                    println!(
84                        "[CallableCache::get_all_jambonz_entries] Failed to deserialize entry: {}",
85                        e
86                    );
87                }
88            }
89        }
90
91        println!(
92            "[CallableCache::get_all_jambonz_entries] Found {} total entries",
93            entries.len()
94        );
95        Ok(entries)
96    }
97
98    /// Deletes a Jambonz entry from Redis.
99    ///
100    /// # Arguments
101    /// * `sip_realm` - The SIP realm to delete
102    ///
103    /// # Returns
104    /// * `Result<bool, RedisError>` - true if deleted, false if not found
105    pub async fn delete_jambonz_entry(
106        &self,
107        sip_realm: &str,
108    ) -> Result<bool, RedisError> {
109        println!(
110            "[CallableCache::delete_jambonz_entry] Deleting Jambonz entry for realm: {}",
111            sip_realm
112        );
113
114        let mut con = self.redis_connection();
115        let deleted: bool = con.hdel(JAMBONZ_KEY, sip_realm).await?;
116
117        if deleted {
118            println!("[CallableCache::delete_jambonz_entry] Successfully deleted Jambonz entry");
119        } else {
120            println!("[CallableCache::delete_jambonz_entry] Entry not found");
121        }
122
123        Ok(deleted)
124    }
125
126    /// Batch insert multiple Jambonz entries.
127    ///
128    /// # Arguments
129    /// * `entries` - Vector of Jambonz entries to insert
130    ///
131    /// # Returns
132    /// * `Result<(), RedisError>` - Ok if successful, or a Redis error
133    pub async fn insert_jambonz_entries(&self, entries: Vec<JambonzEntry>) -> Result<(), RedisError> {
134        println!(
135            "[CallableCache::insert_jambonz_entries] Inserting {} Jambonz entries",
136            entries.len()
137        );
138
139        if entries.is_empty() {
140            return Ok(());
141        }
142
143        let mut con = self.redis_connection();
144        let mut pipe = redis::pipe();
145
146        for entry in entries {
147            let value = serialize_to_json(&entry)?;
148            pipe.hset(JAMBONZ_KEY, &entry.sip_realm, value);
149        }
150
151        pipe.query_async(&mut con).await?;
152
153        println!("[CallableCache::insert_jambonz_entries] Successfully inserted all entries");
154        Ok(())
155    }
156}