use std::sync::{Arc, Mutex};
use std::time::Duration;
use crate::error::Result;
use crate::model::{ProcessorDefinition, RouteContext};
use crate::spi::Processor;
use super::support::StrategyDefinition;
#[derive(Clone, Debug)]
pub enum EipOption {
ParallelProcessing(bool),
Streaming(bool),
StopOnException(bool),
ShareUnitOfWork(bool),
Timeout(Duration),
AggregationStrategy(StrategyDefinition),
Delimiter(String),
IgnoreInvalidEndpoints(bool),
Copy(bool),
AggregateOnException(bool),
PoolSize(usize),
}
impl EipOption {
pub fn name(&self) -> &'static str {
match self {
EipOption::ParallelProcessing(_) => "parallelProcessing",
EipOption::Streaming(_) => "streaming",
EipOption::StopOnException(_) => "stopOnException",
EipOption::ShareUnitOfWork(_) => "shareUnitOfWork",
EipOption::Timeout(_) => "timeout",
EipOption::AggregationStrategy(_) => "aggregationStrategy",
EipOption::Delimiter(_) => "delimiter",
EipOption::IgnoreInvalidEndpoints(_) => "ignoreInvalidEndpoints",
EipOption::Copy(_) => "copy",
EipOption::AggregateOnException(_) => "aggregateOnException",
EipOption::PoolSize(_) => "executorService",
}
}
}
pub trait EipOptions {
fn apply_option(&mut self, option: &EipOption) -> bool;
}
pub trait OptionTarget: Send + Sync {
fn apply(&self, option: &EipOption) -> bool;
fn with_any(&self, f: &mut dyn FnMut(&mut dyn std::any::Any));
}
pub struct Deferred<T: ProcessorDefinition + EipOptions> {
pub inner: Arc<Mutex<T>>,
name: String,
}
impl<T: ProcessorDefinition + EipOptions> Deferred<T> {
pub fn new(def: T) -> Self {
let name = def.name().to_string();
Deferred { inner: Arc::new(Mutex::new(def)), name }
}
}
impl<T: ProcessorDefinition + EipOptions> OptionTarget for Mutex<T> {
fn apply(&self, option: &EipOption) -> bool {
self.lock().unwrap().apply_option(option)
}
fn with_any(&self, f: &mut dyn FnMut(&mut dyn std::any::Any)) {
let mut g = self.lock().unwrap();
f(g.as_any_mut())
}
}
impl<T: ProcessorDefinition + EipOptions> ProcessorDefinition for Deferred<T> {
fn name(&self) -> &str {
&self.name
}
fn create_processor(&self, rc: &RouteContext) -> Result<Arc<dyn Processor>> {
self.inner.lock().unwrap().create_processor(rc)
}
fn id(&self) -> Option<&str> {
None
}
fn set_id(&mut self, id: String) {
self.inner.lock().unwrap().set_id(id)
}
fn label(&self) -> String {
self.inner.lock().unwrap().label()
}
fn wrap_in_channel(&self) -> bool {
self.inner.lock().unwrap().wrap_in_channel()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}
#[derive(Clone, Debug, Default)]
pub struct MulticastSettings {
pub parallel_processing: bool,
pub streaming: bool,
pub stop_on_exception: bool,
pub share_unit_of_work: bool,
pub timeout: Option<Duration>,
pub strategy: Option<StrategyDefinition>,
pub pool_size: Option<usize>,
}
impl MulticastSettings {
pub fn apply(&mut self, option: &EipOption) -> bool {
match option {
EipOption::ParallelProcessing(b) => self.parallel_processing = *b,
EipOption::Streaming(b) => self.streaming = *b,
EipOption::StopOnException(b) => self.stop_on_exception = *b,
EipOption::ShareUnitOfWork(b) => self.share_unit_of_work = *b,
EipOption::Timeout(d) => self.timeout = Some(*d),
EipOption::AggregationStrategy(s) => self.strategy = Some(s.clone()),
EipOption::PoolSize(n) => self.pool_size = Some(*n),
_ => return false,
}
true
}
}