1use crate::error::Result;
12use crate::shared::TransportMessage;
13use crate::types::{JSONRPCNotification, JSONRPCRequest, JSONRPCResponse};
14use async_trait::async_trait;
15use dashmap::DashMap;
16use parking_lot::RwLock;
17use std::fmt;
18use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
19use std::sync::Arc;
20use std::time::Duration;
21use web_time::Instant;
26
27#[derive(Debug, Clone)]
29pub struct MiddlewareContext {
30 pub request_id: Option<String>,
32 pub metadata: Arc<DashMap<String, String>>,
34 pub metrics: Arc<PerformanceMetrics>,
36 pub start_time: Instant,
38 pub priority: Option<crate::shared::transport::MessagePriority>,
40}
41
42impl Default for MiddlewareContext {
43 fn default() -> Self {
44 Self {
45 request_id: None,
46 metadata: Arc::new(DashMap::new()),
47 metrics: Arc::new(PerformanceMetrics::new()),
48 start_time: Instant::now(),
49 priority: None,
50 }
51 }
52}
53
54impl MiddlewareContext {
55 pub fn with_request_id(request_id: String) -> Self {
57 Self {
58 request_id: Some(request_id),
59 ..Default::default()
60 }
61 }
62
63 pub fn set_metadata(&self, key: String, value: String) {
65 self.metadata.insert(key, value);
66 }
67
68 pub fn get_metadata(&self, key: &str) -> Option<String> {
70 self.metadata.get(key).map(|v| v.clone())
71 }
72
73 pub fn record_metric(&self, name: String, value: f64) {
75 self.metrics.record(name, value);
76 }
77
78 pub fn elapsed(&self) -> Duration {
80 self.start_time.elapsed()
81 }
82}
83
84#[derive(Debug, Default)]
86pub struct PerformanceMetrics {
87 metrics: DashMap<String, f64>,
89 request_count: AtomicU64,
91 error_count: AtomicU64,
93 total_time_us: AtomicU64,
95}
96
97impl PerformanceMetrics {
98 pub fn new() -> Self {
100 Self::default()
101 }
102
103 pub fn record(&self, name: String, value: f64) {
105 self.metrics.insert(name, value);
106 }
107
108 pub fn get(&self, name: &str) -> Option<f64> {
110 self.metrics.get(name).map(|v| *v)
111 }
112
113 pub fn inc_requests(&self) {
115 self.request_count.fetch_add(1, Ordering::Relaxed);
116 }
117
118 pub fn inc_errors(&self) {
120 self.error_count.fetch_add(1, Ordering::Relaxed);
121 }
122
123 pub fn add_time(&self, duration: Duration) {
125 self.total_time_us
126 .fetch_add(duration.as_micros() as u64, Ordering::Relaxed);
127 }
128
129 pub fn request_count(&self) -> u64 {
131 self.request_count.load(Ordering::Relaxed)
132 }
133
134 pub fn error_count(&self) -> u64 {
136 self.error_count.load(Ordering::Relaxed)
137 }
138
139 pub fn average_time(&self) -> Duration {
141 let total_time = self.total_time_us.load(Ordering::Relaxed);
142 let count = self.request_count.load(Ordering::Relaxed);
143 total_time
144 .checked_div(count)
145 .map_or(Duration::ZERO, Duration::from_micros)
146 }
147}
148
149#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
151pub enum MiddlewarePriority {
152 Critical = 0,
154 High = 1,
156 #[default]
158 Normal = 2,
159 Low = 3,
161 Lowest = 4,
163}
164
165#[async_trait]
167pub trait AdvancedMiddleware: Send + Sync {
168 fn priority(&self) -> MiddlewarePriority {
170 MiddlewarePriority::Normal
171 }
172
173 fn name(&self) -> &'static str {
175 "unknown"
176 }
177
178 async fn should_execute(&self, _context: &MiddlewareContext) -> bool {
180 true
181 }
182
183 async fn on_request_with_context(
185 &self,
186 request: &mut JSONRPCRequest,
187 context: &MiddlewareContext,
188 ) -> Result<()> {
189 let _ = (request, context);
190 Ok(())
191 }
192
193 async fn on_response_with_context(
195 &self,
196 response: &mut JSONRPCResponse,
197 context: &MiddlewareContext,
198 ) -> Result<()> {
199 let _ = (response, context);
200 Ok(())
201 }
202
203 async fn on_send_with_context(
205 &self,
206 message: &TransportMessage,
207 context: &MiddlewareContext,
208 ) -> Result<()> {
209 let _ = (message, context);
210 Ok(())
211 }
212
213 async fn on_receive_with_context(
215 &self,
216 message: &TransportMessage,
217 context: &MiddlewareContext,
218 ) -> Result<()> {
219 let _ = (message, context);
220 Ok(())
221 }
222
223 async fn on_notification_with_context(
229 &self,
230 notification: &mut JSONRPCNotification,
231 context: &MiddlewareContext,
232 ) -> Result<()> {
233 let _ = (notification, context);
234 Ok(())
235 }
236
237 async fn on_chain_start(&self, _context: &MiddlewareContext) -> Result<()> {
239 Ok(())
240 }
241
242 async fn on_chain_complete(&self, _context: &MiddlewareContext) -> Result<()> {
244 Ok(())
245 }
246
247 async fn on_error(
249 &self,
250 _error: &crate::error::Error,
251 _context: &MiddlewareContext,
252 ) -> Result<()> {
253 Ok(())
254 }
255}
256
257#[async_trait]
311pub trait Middleware: Send + Sync {
312 async fn on_request(&self, request: &mut JSONRPCRequest) -> Result<()> {
314 let _ = request;
315 Ok(())
316 }
317
318 async fn on_response(&self, response: &mut JSONRPCResponse) -> Result<()> {
320 let _ = response;
321 Ok(())
322 }
323
324 async fn on_send(&self, message: &TransportMessage) -> Result<()> {
326 let _ = message;
327 Ok(())
328 }
329
330 async fn on_receive(&self, message: &TransportMessage) -> Result<()> {
332 let _ = message;
333 Ok(())
334 }
335
336 async fn on_notification(&self, notification: &mut JSONRPCNotification) -> Result<()> {
342 let _ = notification;
343 Ok(())
344 }
345}
346
347pub struct EnhancedMiddlewareChain {
378 middlewares: Vec<Arc<dyn AdvancedMiddleware>>,
379 auto_sort: bool,
380}
381
382impl fmt::Debug for EnhancedMiddlewareChain {
383 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
384 f.debug_struct("EnhancedMiddlewareChain")
385 .field("count", &self.middlewares.len())
386 .field("auto_sort", &self.auto_sort)
387 .finish()
388 }
389}
390
391impl Default for EnhancedMiddlewareChain {
392 fn default() -> Self {
393 Self::new()
394 }
395}
396
397impl EnhancedMiddlewareChain {
398 pub fn new() -> Self {
400 Self {
401 middlewares: Vec::new(),
402 auto_sort: true,
403 }
404 }
405
406 pub fn new_no_sort() -> Self {
408 Self {
409 middlewares: Vec::new(),
410 auto_sort: false,
411 }
412 }
413
414 pub fn add(&mut self, middleware: Arc<dyn AdvancedMiddleware>) {
416 self.middlewares.push(middleware);
417 if self.auto_sort {
418 self.sort_by_priority();
419 }
420 }
421
422 pub fn sort_by_priority(&mut self) {
424 self.middlewares.sort_by_key(|m| m.priority());
425 }
426
427 pub fn len(&self) -> usize {
429 self.middlewares.len()
430 }
431
432 pub fn is_empty(&self) -> bool {
434 self.middlewares.is_empty()
435 }
436
437 pub async fn process_request_with_context(
439 &self,
440 request: &mut JSONRPCRequest,
441 context: &MiddlewareContext,
442 ) -> Result<()> {
443 context.metrics.inc_requests();
444 let start_time = Instant::now();
445
446 for middleware in &self.middlewares {
448 if middleware.should_execute(context).await {
449 middleware.on_chain_start(context).await?;
450 }
451 }
452
453 for middleware in &self.middlewares {
455 if middleware.should_execute(context).await {
456 if let Err(e) = middleware.on_request_with_context(request, context).await {
457 context.metrics.inc_errors();
458 for m in &self.middlewares {
460 if m.should_execute(context).await {
461 let _ = m.on_error(&e, context).await;
462 }
463 }
464 return Err(e);
465 }
466 }
467 }
468
469 for middleware in &self.middlewares {
471 if middleware.should_execute(context).await {
472 middleware.on_chain_complete(context).await?;
473 }
474 }
475
476 context.metrics.add_time(start_time.elapsed());
477 Ok(())
478 }
479
480 pub async fn process_response_with_context(
482 &self,
483 response: &mut JSONRPCResponse,
484 context: &MiddlewareContext,
485 ) -> Result<()> {
486 let start_time = Instant::now();
487
488 for middleware in self.middlewares.iter().rev() {
490 if middleware.should_execute(context).await {
491 if let Err(e) = middleware.on_response_with_context(response, context).await {
492 context.metrics.inc_errors();
493 for m in &self.middlewares {
495 if m.should_execute(context).await {
496 let _ = m.on_error(&e, context).await;
497 }
498 }
499 return Err(e);
500 }
501 }
502 }
503
504 context.metrics.add_time(start_time.elapsed());
505 Ok(())
506 }
507
508 pub async fn process_send_with_context(
510 &self,
511 message: &TransportMessage,
512 context: &MiddlewareContext,
513 ) -> Result<()> {
514 let start_time = Instant::now();
515
516 for middleware in &self.middlewares {
517 if middleware.should_execute(context).await {
518 if let Err(e) = middleware.on_send_with_context(message, context).await {
519 context.metrics.inc_errors();
520 for m in &self.middlewares {
521 if m.should_execute(context).await {
522 let _ = m.on_error(&e, context).await;
523 }
524 }
525 return Err(e);
526 }
527 }
528 }
529
530 context.metrics.add_time(start_time.elapsed());
531 Ok(())
532 }
533
534 pub async fn process_receive_with_context(
536 &self,
537 message: &TransportMessage,
538 context: &MiddlewareContext,
539 ) -> Result<()> {
540 let start_time = Instant::now();
541
542 for middleware in &self.middlewares {
543 if middleware.should_execute(context).await {
544 if let Err(e) = middleware.on_receive_with_context(message, context).await {
545 context.metrics.inc_errors();
546 for m in &self.middlewares {
547 if m.should_execute(context).await {
548 let _ = m.on_error(&e, context).await;
549 }
550 }
551 return Err(e);
552 }
553 }
554 }
555
556 context.metrics.add_time(start_time.elapsed());
557 Ok(())
558 }
559
560 pub async fn process_notification_with_context(
591 &self,
592 notification: &mut JSONRPCNotification,
593 context: &MiddlewareContext,
594 ) -> Result<()> {
595 let start_time = Instant::now();
596
597 for middleware in &self.middlewares {
599 if middleware.should_execute(context).await {
600 if let Err(e) = middleware
601 .on_notification_with_context(notification, context)
602 .await
603 {
604 context.metrics.inc_errors();
605 for m in &self.middlewares {
607 if m.should_execute(context).await {
608 let _ = m.on_error(&e, context).await;
609 }
610 }
611 return Err(e);
612 }
613 }
614 }
615
616 context.metrics.add_time(start_time.elapsed());
617 Ok(())
618 }
619
620 pub fn get_metrics(&self) -> Vec<Arc<PerformanceMetrics>> {
622 Vec::new()
625 }
626}
627
628pub struct MiddlewareChain {
681 middlewares: Vec<Arc<dyn Middleware>>,
682}
683
684impl fmt::Debug for MiddlewareChain {
685 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
686 f.debug_struct("MiddlewareChain")
687 .field("count", &self.middlewares.len())
688 .finish()
689 }
690}
691
692impl Default for MiddlewareChain {
693 fn default() -> Self {
694 Self::new()
695 }
696}
697
698impl MiddlewareChain {
699 pub fn new() -> Self {
701 Self {
702 middlewares: Vec::new(),
703 }
704 }
705
706 pub fn add(&mut self, middleware: Arc<dyn Middleware>) {
708 self.middlewares.push(middleware);
709 }
710
711 pub async fn process_request(&self, request: &mut JSONRPCRequest) -> Result<()> {
713 for middleware in &self.middlewares {
714 middleware.on_request(request).await?;
715 }
716 Ok(())
717 }
718
719 pub async fn process_response(&self, response: &mut JSONRPCResponse) -> Result<()> {
721 for middleware in &self.middlewares {
722 middleware.on_response(response).await?;
723 }
724 Ok(())
725 }
726
727 pub async fn process_send(&self, message: &TransportMessage) -> Result<()> {
729 for middleware in &self.middlewares {
730 middleware.on_send(message).await?;
731 }
732 Ok(())
733 }
734
735 pub async fn process_receive(&self, message: &TransportMessage) -> Result<()> {
737 for middleware in &self.middlewares {
738 middleware.on_receive(message).await?;
739 }
740 Ok(())
741 }
742
743 pub async fn process_notification(&self, notification: &mut JSONRPCNotification) -> Result<()> {
749 for middleware in &self.middlewares {
750 middleware.on_notification(notification).await?;
751 }
752 Ok(())
753 }
754}
755
756#[derive(Debug)]
786pub struct LoggingMiddleware {
787 level: tracing::Level,
788}
789
790impl LoggingMiddleware {
791 pub fn new(level: tracing::Level) -> Self {
793 Self { level }
794 }
795}
796
797impl Default for LoggingMiddleware {
798 fn default() -> Self {
799 Self::new(tracing::Level::DEBUG)
800 }
801}
802
803#[async_trait]
804impl Middleware for LoggingMiddleware {
805 async fn on_request(&self, request: &mut JSONRPCRequest) -> Result<()> {
806 match self.level {
807 tracing::Level::TRACE => tracing::trace!("Sending request: {:?}", request),
808 tracing::Level::DEBUG => tracing::debug!("Sending request: {}", request.method),
809 tracing::Level::INFO => tracing::info!("Sending request: {}", request.method),
810 tracing::Level::WARN => tracing::warn!("Sending request: {}", request.method),
811 tracing::Level::ERROR => tracing::error!("Sending request: {}", request.method),
812 }
813 Ok(())
814 }
815
816 async fn on_response(&self, response: &mut JSONRPCResponse) -> Result<()> {
817 match self.level {
818 tracing::Level::TRACE => tracing::trace!("Received response: {:?}", response),
819 tracing::Level::DEBUG => tracing::debug!("Received response for: {:?}", response.id),
820 tracing::Level::INFO => tracing::info!("Received response"),
821 tracing::Level::WARN => tracing::warn!("Received response"),
822 tracing::Level::ERROR => tracing::error!("Received response"),
823 }
824 Ok(())
825 }
826}
827
828#[derive(Debug)]
856pub struct AuthMiddleware {
857 #[allow(dead_code)]
858 auth_token: String,
859}
860
861impl AuthMiddleware {
862 pub fn new(auth_token: String) -> Self {
864 Self { auth_token }
865 }
866}
867
868#[async_trait]
869impl Middleware for AuthMiddleware {
870 async fn on_request(&self, request: &mut JSONRPCRequest) -> Result<()> {
871 tracing::debug!("Adding authentication to request: {}", request.method);
874 Ok(())
875 }
876}
877
878#[derive(Debug)]
916pub struct RetryMiddleware {
917 max_retries: u32,
918 #[allow(dead_code)]
919 initial_delay_ms: u64,
920 #[allow(dead_code)]
921 max_delay_ms: u64,
922}
923
924impl RetryMiddleware {
925 pub fn new(max_retries: u32, initial_delay_ms: u64, max_delay_ms: u64) -> Self {
927 Self {
928 max_retries,
929 initial_delay_ms,
930 max_delay_ms,
931 }
932 }
933}
934
935impl Default for RetryMiddleware {
936 fn default() -> Self {
937 Self::new(3, 1000, 30000)
938 }
939}
940
941#[async_trait]
942impl Middleware for RetryMiddleware {
943 async fn on_request(&self, request: &mut JSONRPCRequest) -> Result<()> {
944 tracing::debug!(
947 "Request {} configured with max {} retries",
948 request.method,
949 self.max_retries
950 );
951 Ok(())
952 }
953}
954
955#[derive(Debug)]
982pub struct RateLimitMiddleware {
983 max_requests: u32,
984 bucket_size: u32,
985 refill_duration: Duration,
986 tokens: Arc<AtomicUsize>,
987 last_refill: Arc<RwLock<Instant>>,
988}
989
990impl RateLimitMiddleware {
991 pub fn new(max_requests: u32, bucket_size: u32, refill_duration: Duration) -> Self {
993 Self {
994 max_requests,
995 bucket_size,
996 refill_duration,
997 tokens: Arc::new(AtomicUsize::new(bucket_size as usize)),
998 last_refill: Arc::new(RwLock::new(Instant::now())),
999 }
1000 }
1001
1002 fn check_rate_limit(&self) -> bool {
1004 let now = Instant::now();
1006 let mut last_refill = self.last_refill.write();
1007 let elapsed = now.duration_since(*last_refill);
1008
1009 if elapsed >= self.refill_duration {
1010 let refill_count = (elapsed.as_millis() / self.refill_duration.as_millis()) as u32;
1011 let tokens_to_add = (refill_count * self.max_requests).min(self.bucket_size);
1012
1013 self.tokens.store(
1014 (self.tokens.load(Ordering::Relaxed) + tokens_to_add as usize)
1015 .min(self.bucket_size as usize),
1016 Ordering::Relaxed,
1017 );
1018 *last_refill = now;
1019 }
1020
1021 loop {
1023 let current = self.tokens.load(Ordering::Relaxed);
1024 if current == 0 {
1025 return false;
1026 }
1027 if self
1028 .tokens
1029 .compare_exchange_weak(current, current - 1, Ordering::Relaxed, Ordering::Relaxed)
1030 .is_ok()
1031 {
1032 return true;
1033 }
1034 }
1035 }
1036}
1037
1038#[async_trait]
1039impl AdvancedMiddleware for RateLimitMiddleware {
1040 fn name(&self) -> &'static str {
1041 "rate_limit"
1042 }
1043
1044 fn priority(&self) -> MiddlewarePriority {
1045 MiddlewarePriority::High
1046 }
1047
1048 async fn on_request_with_context(
1049 &self,
1050 request: &mut JSONRPCRequest,
1051 context: &MiddlewareContext,
1052 ) -> Result<()> {
1053 if !self.check_rate_limit() {
1054 tracing::warn!("Rate limit exceeded for request: {}", request.method);
1055 context.record_metric("rate_limit_exceeded".to_string(), 1.0);
1056 return Err(crate::error::Error::RateLimited);
1057 }
1058
1059 tracing::debug!("Rate limit check passed for request: {}", request.method);
1060 context.record_metric("rate_limit_passed".to_string(), 1.0);
1061 Ok(())
1062 }
1063}
1064
1065#[derive(Debug)]
1096pub struct CircuitBreakerMiddleware {
1097 failure_threshold: u32,
1098 time_window: Duration,
1099 timeout_duration: Duration,
1100 failure_count: Arc<AtomicU64>,
1101 last_failure: Arc<RwLock<Option<Instant>>>,
1102 circuit_open_time: Arc<RwLock<Option<Instant>>>,
1103}
1104
1105impl CircuitBreakerMiddleware {
1106 pub fn new(failure_threshold: u32, time_window: Duration, timeout_duration: Duration) -> Self {
1108 Self {
1109 failure_threshold,
1110 time_window,
1111 timeout_duration,
1112 failure_count: Arc::new(AtomicU64::new(0)),
1113 last_failure: Arc::new(RwLock::new(None)),
1114 circuit_open_time: Arc::new(RwLock::new(None)),
1115 }
1116 }
1117
1118 fn should_allow_request(&self) -> bool {
1120 let now = Instant::now();
1121
1122 let open_time_value = *self.circuit_open_time.read();
1124 if let Some(open_time) = open_time_value {
1125 if now.duration_since(open_time) > self.timeout_duration {
1126 *self.circuit_open_time.write() = None;
1128 self.failure_count.store(0, Ordering::Relaxed);
1129 return true;
1130 }
1131 return false; }
1133
1134 let last_failure_value = *self.last_failure.read();
1136 if let Some(last_failure) = last_failure_value {
1137 if now.duration_since(last_failure) > self.time_window {
1138 self.failure_count.store(0, Ordering::Relaxed);
1139 }
1140 }
1141
1142 self.failure_count.load(Ordering::Relaxed) < self.failure_threshold as u64
1144 }
1145
1146 fn record_failure(&self) {
1148 let now = Instant::now();
1149 let failures = self.failure_count.fetch_add(1, Ordering::Relaxed) + 1;
1150 *self.last_failure.write() = Some(now);
1151
1152 if failures >= self.failure_threshold as u64 {
1153 *self.circuit_open_time.write() = Some(now);
1154 tracing::warn!("Circuit breaker opened due to {} failures", failures);
1155 }
1156 }
1157}
1158
1159#[async_trait]
1160impl AdvancedMiddleware for CircuitBreakerMiddleware {
1161 fn name(&self) -> &'static str {
1162 "circuit_breaker"
1163 }
1164
1165 fn priority(&self) -> MiddlewarePriority {
1166 MiddlewarePriority::High
1167 }
1168
1169 async fn on_request_with_context(
1170 &self,
1171 request: &mut JSONRPCRequest,
1172 context: &MiddlewareContext,
1173 ) -> Result<()> {
1174 if !self.should_allow_request() {
1175 tracing::warn!(
1176 "Circuit breaker open, rejecting request: {}",
1177 request.method
1178 );
1179 context.record_metric("circuit_breaker_open".to_string(), 1.0);
1180 return Err(crate::error::Error::CircuitBreakerOpen);
1181 }
1182
1183 context.record_metric("circuit_breaker_allowed".to_string(), 1.0);
1184 Ok(())
1185 }
1186
1187 async fn on_error(
1188 &self,
1189 _error: &crate::error::Error,
1190 _context: &MiddlewareContext,
1191 ) -> Result<()> {
1192 self.record_failure();
1193 Ok(())
1194 }
1195}
1196
1197#[derive(Debug)]
1222pub struct MetricsMiddleware {
1223 service_name: String,
1224 request_counts: Arc<DashMap<String, AtomicU64>>,
1225 request_durations: Arc<DashMap<String, AtomicU64>>,
1226 error_counts: Arc<DashMap<String, AtomicU64>>,
1227}
1228
1229impl MetricsMiddleware {
1230 pub fn new(service_name: String) -> Self {
1232 Self {
1233 service_name,
1234 request_counts: Arc::new(DashMap::new()),
1235 request_durations: Arc::new(DashMap::new()),
1236 error_counts: Arc::new(DashMap::new()),
1237 }
1238 }
1239
1240 pub fn get_request_count(&self, method: &str) -> u64 {
1242 self.request_counts
1243 .get(method)
1244 .map_or(0, |c| c.load(Ordering::Relaxed))
1245 }
1246
1247 pub fn get_error_count(&self, method: &str) -> u64 {
1249 self.error_counts
1250 .get(method)
1251 .map_or(0, |c| c.load(Ordering::Relaxed))
1252 }
1253
1254 pub fn get_average_duration(&self, method: &str) -> u64 {
1256 let total_duration = self
1257 .request_durations
1258 .get(method)
1259 .map_or(0, |d| d.load(Ordering::Relaxed));
1260 let count = self.get_request_count(method);
1261 total_duration.checked_div(count).unwrap_or(0)
1262 }
1263}
1264
1265#[async_trait]
1266impl AdvancedMiddleware for MetricsMiddleware {
1267 fn name(&self) -> &'static str {
1268 "metrics"
1269 }
1270
1271 fn priority(&self) -> MiddlewarePriority {
1272 MiddlewarePriority::Low
1273 }
1274
1275 async fn on_request_with_context(
1276 &self,
1277 request: &mut JSONRPCRequest,
1278 context: &MiddlewareContext,
1279 ) -> Result<()> {
1280 self.request_counts
1282 .entry(request.method.clone())
1283 .or_insert_with(|| AtomicU64::new(0))
1284 .fetch_add(1, Ordering::Relaxed);
1285
1286 context.set_metadata(
1287 "request_start_time".to_string(),
1288 context.start_time.elapsed().as_micros().to_string(),
1289 );
1290 context.set_metadata("service_name".to_string(), self.service_name.clone());
1291
1292 tracing::debug!(
1293 "Metrics recorded for request: {} (service: {})",
1294 request.method,
1295 self.service_name
1296 );
1297 Ok(())
1298 }
1299
1300 async fn on_response_with_context(
1301 &self,
1302 response: &mut JSONRPCResponse,
1303 context: &MiddlewareContext,
1304 ) -> Result<()> {
1305 let duration_us = context.elapsed().as_micros() as u64;
1307
1308 if let Some(method) = context.get_metadata("method") {
1309 self.request_durations
1310 .entry(method)
1311 .or_insert_with(|| AtomicU64::new(0))
1312 .fetch_add(duration_us, Ordering::Relaxed);
1313 }
1314
1315 tracing::debug!(
1316 "Response metrics recorded for ID: {:?} ({}μs)",
1317 response.id,
1318 duration_us
1319 );
1320 Ok(())
1321 }
1322
1323 async fn on_error(
1324 &self,
1325 error: &crate::error::Error,
1326 context: &MiddlewareContext,
1327 ) -> Result<()> {
1328 if let Some(method) = context.get_metadata("method") {
1329 self.error_counts
1330 .entry(method)
1331 .or_insert_with(|| AtomicU64::new(0))
1332 .fetch_add(1, Ordering::Relaxed);
1333 }
1334
1335 tracing::warn!("Error recorded in metrics: {:?}", error);
1336 Ok(())
1337 }
1338}
1339
1340#[derive(Debug, Clone, Copy)]
1365pub enum CompressionType {
1366 None,
1368 Gzip,
1370 Deflate,
1372}
1373
1374#[derive(Debug)]
1376pub struct CompressionMiddleware {
1377 compression_type: CompressionType,
1378 min_size: usize,
1379}
1380
1381impl CompressionMiddleware {
1382 pub fn new(compression_type: CompressionType, min_size: usize) -> Self {
1384 Self {
1385 compression_type,
1386 min_size,
1387 }
1388 }
1389
1390 fn should_compress(&self, content_size: usize) -> bool {
1392 content_size >= self.min_size && !matches!(self.compression_type, CompressionType::None)
1393 }
1394}
1395
1396#[async_trait]
1397impl AdvancedMiddleware for CompressionMiddleware {
1398 fn name(&self) -> &'static str {
1399 "compression"
1400 }
1401
1402 fn priority(&self) -> MiddlewarePriority {
1403 MiddlewarePriority::Normal
1404 }
1405
1406 async fn on_send_with_context(
1407 &self,
1408 message: &TransportMessage,
1409 context: &MiddlewareContext,
1410 ) -> Result<()> {
1411 let serialized = serde_json::to_string(message).unwrap_or_default();
1412 let content_size = serialized.len();
1413
1414 if self.should_compress(content_size) {
1415 context.set_metadata(
1416 "compression_type".to_string(),
1417 format!("{:?}", self.compression_type),
1418 );
1419 context.record_metric("compression_original_size".to_string(), content_size as f64);
1420
1421 tracing::debug!("Compression applied to message of {} bytes", content_size);
1422 }
1424
1425 Ok(())
1426 }
1427}
1428
1429#[cfg(test)]
1430mod tests {
1431 use super::*;
1432 use crate::types::RequestId;
1433
1434 #[tokio::test]
1435 async fn test_middleware_chain() {
1436 let mut chain = MiddlewareChain::new();
1437 chain.add(Arc::new(LoggingMiddleware::default()));
1438
1439 let mut request = JSONRPCRequest {
1440 jsonrpc: "2.0".to_string(),
1441 id: RequestId::from(1i64),
1442 method: "test".to_string(),
1443 params: None,
1444 };
1445
1446 assert!(chain.process_request(&mut request).await.is_ok());
1447 }
1448
1449 #[tokio::test]
1450 async fn test_auth_middleware() {
1451 let middleware = AuthMiddleware::new("test-token".to_string());
1452
1453 let mut request = JSONRPCRequest {
1454 jsonrpc: "2.0".to_string(),
1455 id: RequestId::from(1i64),
1456 method: "test".to_string(),
1457 params: None,
1458 };
1459
1460 assert!(middleware.on_request(&mut request).await.is_ok());
1461 }
1462
1463 #[tokio::test]
1464 async fn test_notification_middleware_legacy() {
1465 let mut chain = MiddlewareChain::new();
1466 chain.add(Arc::new(LoggingMiddleware::default()));
1467
1468 let mut notification = JSONRPCNotification::new(
1469 "notifications/progress",
1470 Some(serde_json::json!({
1471 "progressToken": "test-123",
1472 "progress": 50,
1473 "total": 100
1474 })),
1475 );
1476
1477 assert!(chain.process_notification(&mut notification).await.is_ok());
1479 }
1480
1481 #[tokio::test]
1482 async fn test_notification_middleware_enhanced() {
1483 let mut chain = EnhancedMiddlewareChain::new();
1484 chain.add(Arc::new(MetricsMiddleware::new("test-service".to_string())));
1485
1486 let context = MiddlewareContext::with_request_id("notif-001".to_string());
1487
1488 let mut notification = JSONRPCNotification::new(
1489 "notifications/resourceUpdated",
1490 Some(serde_json::json!({
1491 "uri": "file:///test.txt",
1492 "type": "modified"
1493 })),
1494 );
1495
1496 assert!(chain
1498 .process_notification_with_context(&mut notification, &context)
1499 .await
1500 .is_ok());
1501
1502 let stats = context.metrics;
1504 assert_eq!(stats.request_count(), 0);
1505 }
1506
1507 struct NotificationMetadataMiddleware {
1509 tag: String,
1510 }
1511
1512 #[async_trait::async_trait]
1513 impl AdvancedMiddleware for NotificationMetadataMiddleware {
1514 fn name(&self) -> &'static str {
1515 "notification_metadata"
1516 }
1517
1518 async fn on_notification_with_context(
1519 &self,
1520 notification: &mut JSONRPCNotification,
1521 context: &MiddlewareContext,
1522 ) -> Result<()> {
1523 context.set_metadata(
1525 "notification_method".to_string(),
1526 notification.method.clone(),
1527 );
1528 context.set_metadata("middleware_tag".to_string(), self.tag.clone());
1529 Ok(())
1530 }
1531 }
1532
1533 #[tokio::test]
1534 async fn test_notification_metadata_middleware() {
1535 let mut chain = EnhancedMiddlewareChain::new();
1536 chain.add(Arc::new(NotificationMetadataMiddleware {
1537 tag: "test-tag".to_string(),
1538 }));
1539
1540 let context = MiddlewareContext::with_request_id("notif-002".to_string());
1541
1542 let mut notification = JSONRPCNotification::new(
1543 "notifications/cancelled",
1544 Some(serde_json::json!({
1545 "requestId": "req-123",
1546 "reason": "user cancelled"
1547 })),
1548 );
1549
1550 chain
1551 .process_notification_with_context(&mut notification, &context)
1552 .await
1553 .unwrap();
1554
1555 assert_eq!(
1557 context.get_metadata("notification_method"),
1558 Some("notifications/cancelled".to_string())
1559 );
1560 assert_eq!(
1561 context.get_metadata("middleware_tag"),
1562 Some("test-tag".to_string())
1563 );
1564 }
1565
1566 #[tokio::test]
1567 async fn test_notification_error_handling() {
1568 struct FailingNotificationMiddleware;
1570
1571 #[async_trait::async_trait]
1572 impl AdvancedMiddleware for FailingNotificationMiddleware {
1573 fn name(&self) -> &'static str {
1574 "failing_notification"
1575 }
1576
1577 async fn on_notification_with_context(
1578 &self,
1579 notification: &mut JSONRPCNotification,
1580 _context: &MiddlewareContext,
1581 ) -> Result<()> {
1582 if notification.method == "notifications/error" {
1583 return Err(crate::Error::internal("notification processing failed"));
1584 }
1585 Ok(())
1586 }
1587 }
1588
1589 let mut chain = EnhancedMiddlewareChain::new();
1590 chain.add(Arc::new(FailingNotificationMiddleware));
1591
1592 let context = MiddlewareContext::default();
1593
1594 let mut ok_notification =
1596 JSONRPCNotification::new("notifications/ok", None::<serde_json::Value>);
1597 assert!(chain
1598 .process_notification_with_context(&mut ok_notification, &context)
1599 .await
1600 .is_ok());
1601
1602 let mut error_notification =
1604 JSONRPCNotification::new("notifications/error", None::<serde_json::Value>);
1605 let result = chain
1606 .process_notification_with_context(&mut error_notification, &context)
1607 .await;
1608 assert!(result.is_err());
1609
1610 assert_eq!(context.metrics.error_count(), 1);
1612 }
1613}