use std::mem;
use praxis_core::config::FilterEntry;
use tracing::debug;
use super::{FilterPipeline, body::compute_body_capabilities};
use crate::{FilterError, any_filter::AnyFilter, registry::FilterRegistry};
impl FilterPipeline {
pub fn build(entries: &mut [FilterEntry], registry: &FilterRegistry) -> Result<Self, FilterError> {
let mut filters = Vec::with_capacity(entries.len());
for entry in entries.iter_mut() {
let filter = registry.create(&entry.filter_type, &entry.config)?;
let has_conditions = !entry.conditions.is_empty() || !entry.response_conditions.is_empty();
debug!(
filter = filter.name(),
conditions = has_conditions,
"filter added to pipeline"
);
filters.push((
filter,
mem::take(&mut entry.conditions),
mem::take(&mut entry.response_conditions),
));
}
let body_capabilities = compute_body_capabilities(&filters);
let compression = extract_compression_config(&filters);
Ok(Self {
body_capabilities,
compression,
filters,
health_registry: None,
})
}
pub fn ordering_errors(&self, entries: &[FilterEntry]) -> Vec<String> {
let names: Vec<&str> = self.filters.iter().map(|(f, ..)| f.name()).collect();
let mut errors = Vec::new();
super::checks::check_lb_without_router(&names, &mut errors);
super::checks::check_unconditional_static_response(&names, &self.filters, &mut errors);
super::checks::check_conditional_security(&names, &self.filters, &mut errors);
super::checks::check_duplicate_routers(&names, &mut errors);
super::checks::check_duplicate_load_balancers(&names, &mut errors);
super::checks::check_misaligned_clusters(entries, &mut errors);
super::checks::check_duplicate_rewrite_filters(&names, entries, &mut errors);
errors
}
pub fn ordering_warnings(&self) -> Vec<String> {
let names: Vec<&str> = self.filters.iter().map(|(f, ..)| f.name()).collect();
let mut warnings = Vec::new();
super::checks::check_router_without_lb(&names, &mut warnings);
super::checks::check_all_routers_conditional(&names, &self.filters, &mut warnings);
warnings
}
}
fn extract_compression_config(
filters: &[super::ConditionalFilter],
) -> Option<crate::builtins::http::payload_processing::compression_config::CompressionConfig> {
for (filter, ..) in filters {
if let AnyFilter::Http(f) = filter
&& let Some(cfg) = f.compression_config()
{
return Some(cfg.clone());
}
}
None
}