Skip to content

Commit

Permalink
Merge pull request #148 from Kuadrant/145-fold-subsequent-calls-to-li…
Browse files Browse the repository at this point in the history
…mitador-into-a-single-one

Fold subsequent calls to limitador into a single one
  • Loading branch information
eguzki authored Nov 22, 2024
2 parents de863de + bf946b1 commit d180b17
Show file tree
Hide file tree
Showing 18 changed files with 1,721 additions and 527 deletions.
25 changes: 16 additions & 9 deletions src/configuration/action_set_index.rs → src/action_set_index.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::configuration::action_set::ActionSet;
use crate::runtime_action_set::RuntimeActionSet;
use radix_trie::Trie;
use std::rc::Rc;

pub struct ActionSetIndex {
raw_tree: Trie<String, Vec<Rc<ActionSet>>>,
pub(crate) struct ActionSetIndex {
raw_tree: Trie<String, Vec<Rc<RuntimeActionSet>>>,
}

impl ActionSetIndex {
Expand All @@ -13,7 +13,7 @@ impl ActionSetIndex {
}
}

pub fn insert(&mut self, subdomain: &str, action_set: Rc<ActionSet>) {
pub fn insert(&mut self, subdomain: &str, action_set: Rc<RuntimeActionSet>) {
let rev = Self::reverse_subdomain(subdomain);
self.raw_tree.map_with_default(
rev,
Expand All @@ -24,7 +24,10 @@ impl ActionSetIndex {
);
}

pub fn get_longest_match_action_sets(&self, subdomain: &str) -> Option<&Vec<Rc<ActionSet>>> {
pub fn get_longest_match_action_sets(
&self,
subdomain: &str,
) -> Option<&Vec<Rc<RuntimeActionSet>>> {
let rev = Self::reverse_subdomain(subdomain);
self.raw_tree.get_ancestor_value(&rev)
}
Expand All @@ -43,12 +46,16 @@ impl ActionSetIndex {

#[cfg(test)]
mod tests {
use crate::configuration::action_set::ActionSet;
use crate::configuration::action_set_index::ActionSetIndex;
use crate::action_set_index::ActionSetIndex;
use crate::runtime_action_set::RuntimeActionSet;
use std::rc::Rc;

fn build_ratelimit_action_set(name: &str) -> ActionSet {
ActionSet::new(name.to_owned(), Default::default(), Vec::new())
fn build_ratelimit_action_set(name: &str) -> RuntimeActionSet {
RuntimeActionSet {
name: name.to_owned(),
route_rule_predicates: Default::default(),
runtime_actions: Vec::new(),
}
}

#[test]
Expand Down
111 changes: 111 additions & 0 deletions src/auth_action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
use crate::configuration::{Action, FailureMode, Service};
use crate::data::Predicate;
use crate::service::GrpcService;
use log::error;
use std::rc::Rc;

#[derive(Debug)]
pub struct AuthAction {
grpc_service: Rc<GrpcService>,
scope: String,
predicates: Vec<Predicate>,
}

impl AuthAction {
pub fn new(action: &Action, service: &Service) -> Result<Self, String> {
let mut predicates = Vec::default();
for predicate in &action.predicates {
predicates.push(Predicate::new(predicate).map_err(|e| e.to_string())?);
}

Ok(AuthAction {
grpc_service: Rc::new(GrpcService::new(Rc::new(service.clone()))),
scope: action.scope.clone(),
predicates,
})
}

pub fn get_grpcservice(&self) -> Rc<GrpcService> {
Rc::clone(&self.grpc_service)
}

pub fn scope(&self) -> &str {
self.scope.as_str()
}

pub fn conditions_apply(&self) -> bool {
let predicates = &self.predicates;
predicates.is_empty()
|| predicates.iter().all(|predicate| match predicate.test() {
Ok(b) => b,
Err(err) => {
error!("Failed to evaluate {:?}: {}", predicate, err);
panic!("Err out of this!")
}
})
}

pub fn get_failure_mode(&self) -> FailureMode {
self.grpc_service.get_failure_mode()
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::configuration::{Action, FailureMode, Service, ServiceType, Timeout};

fn build_auth_action_with_predicates(predicates: Vec<String>) -> AuthAction {
let action = Action {
service: "some_service".into(),
scope: "some_scope".into(),
predicates,
data: Vec::default(),
};

let service = Service {
service_type: ServiceType::Auth,
endpoint: "some_endpoint".into(),
failure_mode: FailureMode::default(),
timeout: Timeout::default(),
};

AuthAction::new(&action, &service)
.expect("action building failed. Maybe predicates compilation?")
}

#[test]
fn empty_predicates_do_apply() {
let auth_action = build_auth_action_with_predicates(Vec::default());
assert!(auth_action.conditions_apply());
}

#[test]
fn when_all_predicates_are_truthy_action_apply() {
let auth_action = build_auth_action_with_predicates(vec!["true".into(), "true".into()]);
assert!(auth_action.conditions_apply());
}

#[test]
fn when_not_all_predicates_are_truthy_action_does_not_apply() {
let auth_action = build_auth_action_with_predicates(vec![
"true".into(),
"true".into(),
"true".into(),
"false".into(),
]);
assert!(!auth_action.conditions_apply());
}

#[test]
#[should_panic]
fn when_a_cel_expression_does_not_evaluate_to_bool_panics() {
let auth_action = build_auth_action_with_predicates(vec![
"true".into(),
"true".into(),
"true".into(),
"1".into(),
]);
auth_action.conditions_apply();
}
}
Loading

0 comments on commit d180b17

Please sign in to comment.