diff --git a/scylla-server/src/controllers/rule_controller.rs b/scylla-server/src/controllers/rule_controller.rs index bd0d6c09..feb3720a 100644 --- a/scylla-server/src/controllers/rule_controller.rs +++ b/scylla-server/src/controllers/rule_controller.rs @@ -83,6 +83,14 @@ pub async fn get_all_rules_with_client_info( )) } +#[debug_handler] +pub async fn check_rule( + Extension(rules_manager): Extension>, + Json(rule): Json, +) -> Json { + debug!("Checking if rule exists: {} - {}", rule.topic, rule.expr); + Json(rules_manager.check_rule(&rule.topic, &rule.expr).await) +} #[serde_as] #[derive(Deserialize)] pub struct EditRulePayload { diff --git a/scylla-server/src/rule_structs.rs b/scylla-server/src/rule_structs.rs index 5f454084..9fc64956 100644 --- a/scylla-server/src/rule_structs.rs +++ b/scylla-server/src/rule_structs.rs @@ -484,6 +484,13 @@ impl RuleManager { } } } + pub async fn check_rule(&self, topic: &Topic, expr: &str) -> bool { + self.rules + .read() + .await + .values() + .any(|rule| rule.topic == *topic && rule.expr == expr) + } pub async fn edit_rule( &self, diff --git a/scylla-server/tests/rule_structs_test.rs b/scylla-server/tests/rule_structs_test.rs index 47ef8fb8..84120ff3 100644 --- a/scylla-server/tests/rule_structs_test.rs +++ b/scylla-server/tests/rule_structs_test.rs @@ -535,6 +535,66 @@ async fn test_concurrent_high_frequency_messages() -> Result<(), RuleManagerErro } } } + #[tokio::test] + async fn test_check_rule_exists() -> Result<(), RuleManagerError> { + let rule_manager = RuleManager::new(); + let client = ClientId("test_client".to_string()); + + let rule = Rule::new( + RuleId("rule_1".to_string()), + Topic("test/topic".to_string()), + core::time::Duration::from_secs(60), + "a > 10".to_owned(), + ); + + rule_manager.add_rule(client, rule).await?; + + assert!(rule_manager.check_rule(&Topic("test/topic".to_string()), "a > 10").await); + Ok(()) + } + + #[tokio::test] + async fn test_check_rule_wrong_expr() -> Result<(), RuleManagerError> { + let rule_manager = RuleManager::new(); + let client = ClientId("test_client".to_string()); + + let rule = Rule::new( + RuleId("rule_1".to_string()), + Topic("test/topic".to_string()), + core::time::Duration::from_secs(60), + "a > 10".to_owned(), + ); + + rule_manager.add_rule(client, rule).await?; + + assert!(!rule_manager.check_rule(&Topic("test/topic".to_string()), "a > 20").await); + Ok(()) + } + + #[tokio::test] + async fn test_check_rule_wrong_topic() -> Result<(), RuleManagerError> { + let rule_manager = RuleManager::new(); + let client = ClientId("test_client".to_string()); + + let rule = Rule::new( + RuleId("rule_1".to_string()), + Topic("test/topic".to_string()), + core::time::Duration::from_secs(60), + "a > 10".to_owned(), + ); + + rule_manager.add_rule(client, rule).await?; + + assert!(!rule_manager.check_rule(&Topic("wrong/topic".to_string()), "a > 10").await); + Ok(()) + } + + #[tokio::test] + async fn test_check_rule_empty_manager() { + let rule_manager = RuleManager::new(); + + assert!(!rule_manager.check_rule(&Topic("test/topic".to_string()), "a > 10").await); + } // Verify system state is unchanged assert_eq!(rule_manager.get_all_rules().await.len(), num_rules);