1#![allow(clippy::field_reassign_with_default)]
53#![allow(clippy::single_match)]
54#![allow(clippy::collapsible_if)]
55#![allow(clippy::clone_on_copy)]
56#![allow(clippy::type_complexity)]
57#![allow(clippy::collapsible_match)]
58#![allow(clippy::manual_clamp)]
59#![allow(clippy::needless_range_loop)]
60#![allow(clippy::or_fun_call)]
61#![allow(clippy::if_same_then_else)]
62#![allow(clippy::only_used_in_recursion)]
63#![allow(clippy::new_without_default)]
64#![allow(clippy::derivable_impls)]
65#![allow(clippy::useless_conversion)]
66use serde::{Deserialize, Serialize};
67use std::collections::HashMap;
68use std::net::SocketAddr;
69use std::sync::Arc;
70use tokio::sync::RwLock;
71
72pub mod adaptive_leader_election;
73pub mod advanced_partitioning;
74pub mod advanced_storage;
75pub mod alerting;
76pub mod auto_scaling;
77pub mod backup_restore;
78pub mod circuit_breaker;
79pub mod cloud_integration;
80pub mod cluster_metrics;
81pub mod cluster_metrics_manager;
82pub mod cluster_metrics_stats;
83#[cfg(test)]
84mod cluster_metrics_tests;
85pub mod cluster_metrics_types;
86pub mod compression_strategy;
87pub mod conflict_resolution;
88pub mod consensus;
89pub mod crash_recovery;
90pub mod data_rebalancing;
91pub mod disaster_recovery;
92pub mod discovery;
93pub mod distributed_query;
94pub mod distributed_tracing;
95pub mod edge_computing;
96pub mod encryption;
97pub mod enhanced_node_discovery;
98pub mod enhanced_snapshotting;
99pub mod error;
100pub mod failover;
101pub mod federation;
102pub mod gpu_acceleration;
103pub mod health_monitor;
104pub mod health_monitoring;
105pub mod memory_optimization;
106pub mod merkle_tree;
107pub mod ml_optimization;
108pub mod multi_tenant;
109pub mod mvcc;
110pub mod mvcc_storage;
111pub mod network;
112pub mod neural_architecture_search;
113pub mod node_lifecycle;
114pub mod node_status_tracker;
115pub mod operational_transformation;
116pub mod optimization;
117pub mod partition_detection;
118pub mod performance_metrics;
119pub mod performance_monitor;
120pub mod raft;
121#[cfg(feature = "raft")]
122mod raft_network;
123pub mod raft_optimization;
124pub mod raft_profiling;
125pub mod raft_state;
126pub mod range_partitioning;
127pub mod read_replica;
128pub mod region_manager;
129pub mod replication;
130pub mod replication_lag_monitor;
131pub mod rl_consensus_optimizer;
132pub mod rolling_upgrade;
133pub mod rolling_upgrade_orchestrator;
134pub mod split_brain_detector;
135pub mod visualization_dashboard;
136pub mod zero_downtime_migration;
137pub mod cross_dc;
140pub mod network_compression;
141pub mod security;
142pub mod serialization;
143pub mod shard;
144pub mod shard_manager;
145pub mod shard_migration;
146pub mod shard_routing;
147pub mod split_brain_prevention;
148pub mod storage;
149pub mod strong_consistency;
150pub mod tls;
151pub mod topology;
152pub mod transaction;
153pub mod transaction_optimizer;
154
155#[cfg(feature = "bft")]
156pub mod bft;
157#[cfg(feature = "bft")]
158pub mod bft_consensus;
159#[cfg(feature = "bft")]
160pub mod bft_network;
161
162pub mod gossip_scaling;
163pub mod sla_manager;
164pub mod stream_integration;
165
166pub mod adaptive_consistent_hash;
168pub mod cross_dc_consistency;
169pub mod distributed_tx_coordinator;
170
171pub mod vnodes_hash_ring;
173
174pub mod membership_gossip;
176
177pub mod leader_election;
179
180pub mod snapshot_manager;
182
183pub mod consistent_shard_router;
185
186pub mod partition_rebalancer;
188
189pub mod node_monitor;
191
192pub mod failover_manager;
194
195pub mod anti_entropy;
201
202pub mod gossip;
206
207pub mod simulation;
215
216pub mod replication_throttle;
218
219pub mod data_migrator;
222
223pub mod shard_router;
225
226pub mod election_timer;
229
230pub mod compression;
233
234pub mod backup;
237
238pub mod sla;
246
247pub mod streaming;
256
257pub mod log_replication_topology;
265
266pub mod witness_node;
274
275pub mod tcp_cluster;
283
284pub mod certification;
292
293pub use log_replication_topology::{
294 NodeDescriptor, ReplicationRole, ReplicationTopology, TopologyNode,
295};
296pub use tcp_cluster::{
297 ClusterMessage, GossipState, MessageCodec, NetworkStats, TcpClusterNetwork, TcpClusterNode,
298 TcpNodeConfig, TcpNodeError,
299};
300pub use witness_node::{
301 VoteRequest, VoteResponse, WitnessAppendRequest, WitnessAppendResponse, WitnessLogEntry,
302 WitnessNode,
303};
304
305pub use error::{ClusterError, Result};
306pub use failover::{FailoverConfig, FailoverManager, FailoverStrategy, RecoveryAction};
307pub use health_monitor::{HealthMonitor, HealthMonitorConfig, NodeHealth, SystemMetrics};
308
309use conflict_resolution::{
320 ConflictResolver, ResolutionStrategy, TimestampedOperation, VectorClock,
321};
322use consensus::ConsensusManager;
323use discovery::{DiscoveryConfig, DiscoveryService, NodeInfo};
324use distributed_query::{DistributedQueryExecutor, ResultBinding};
325use edge_computing::{EdgeComputingManager, EdgeDeploymentStrategy, EdgeDeviceProfile};
326use raft::{OxirsNodeId, RdfResponse};
327use region_manager::{
328 ConsensusStrategy as RegionConsensusStrategy, MultiRegionReplicationStrategy, Region,
329 RegionManager,
330};
331use replication::{ReplicationManager, ReplicationStats, ReplicationStrategy};
332
333#[derive(Debug, Clone, Serialize, Deserialize)]
335pub struct MultiRegionConfig {
336 pub region_id: String,
338 pub availability_zone_id: String,
340 pub data_center: Option<String>,
342 pub rack: Option<String>,
344 pub regions: Vec<Region>,
346 pub consensus_strategy: RegionConsensusStrategy,
348 pub replication_strategy: MultiRegionReplicationStrategy,
350 pub conflict_resolution_strategy: ResolutionStrategy,
352 pub edge_config: Option<EdgeComputingConfig>,
354 pub enable_monitoring: bool,
356}
357
358#[derive(Debug, Clone, Serialize, Deserialize)]
360pub struct EdgeComputingConfig {
361 pub enabled: bool,
363 pub device_profile: EdgeDeviceProfile,
365 pub deployment_strategy: EdgeDeploymentStrategy,
367 pub enable_intelligent_caching: bool,
369 pub enable_network_monitoring: bool,
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize)]
375pub struct NodeConfig {
376 pub node_id: OxirsNodeId,
378 pub address: SocketAddr,
380 pub data_dir: String,
382 pub peers: Vec<OxirsNodeId>,
384 pub peer_addresses: HashMap<OxirsNodeId, SocketAddr>,
393 pub discovery: Option<DiscoveryConfig>,
395 pub replication_strategy: Option<ReplicationStrategy>,
397 pub use_bft: bool,
404 pub region_config: Option<MultiRegionConfig>,
406}
407
408impl NodeConfig {
409 pub fn new(node_id: OxirsNodeId, address: SocketAddr) -> Self {
411 Self {
412 node_id,
413 address,
414 data_dir: format!("./data/node-{node_id}"),
415 peers: Vec::new(),
416 peer_addresses: HashMap::new(),
417 discovery: Some(DiscoveryConfig::default()),
418 replication_strategy: Some(ReplicationStrategy::default()),
419 use_bft: false,
420 region_config: None,
421 }
422 }
423
424 pub fn add_peer(&mut self, peer_id: OxirsNodeId) -> &mut Self {
426 if !self.peers.contains(&peer_id) && peer_id != self.node_id {
427 self.peers.push(peer_id);
428 }
429 self
430 }
431
432 pub fn add_peer_address(&mut self, peer_id: OxirsNodeId, address: SocketAddr) -> &mut Self {
436 self.peer_addresses.insert(peer_id, address);
437 self
438 }
439
440 pub fn with_discovery(mut self, discovery: DiscoveryConfig) -> Self {
442 self.discovery = Some(discovery);
443 self
444 }
445
446 pub fn with_replication_strategy(mut self, strategy: ReplicationStrategy) -> Self {
448 self.replication_strategy = Some(strategy);
449 self
450 }
451
452 pub fn with_bft(mut self, enable: bool) -> Self {
458 self.use_bft = enable;
459 self
460 }
461
462 pub fn with_multi_region(mut self, region_config: MultiRegionConfig) -> Self {
464 self.region_config = Some(region_config);
465 self
466 }
467
468 pub fn is_multi_region_enabled(&self) -> bool {
470 self.region_config.is_some()
471 }
472
473 pub fn region_id(&self) -> Option<&str> {
475 self.region_config
476 .as_ref()
477 .map(|config| config.region_id.as_str())
478 }
479
480 pub fn availability_zone_id(&self) -> Option<&str> {
482 self.region_config
483 .as_ref()
484 .map(|config| config.availability_zone_id.as_str())
485 }
486}
487
488pub struct ClusterNode {
490 config: NodeConfig,
491 consensus: ConsensusManager,
492 discovery: DiscoveryService,
493 replication: ReplicationManager,
494 query_executor: DistributedQueryExecutor,
495 region_manager: Option<Arc<RegionManager>>,
496 conflict_resolver: Arc<ConflictResolver>,
497 #[allow(dead_code)]
498 edge_manager: Option<Arc<EdgeComputingManager>>,
499 local_vector_clock: Arc<RwLock<VectorClock>>,
500 running: Arc<RwLock<bool>>,
501 byzantine_mode: Arc<RwLock<bool>>,
502 network_isolated: Arc<RwLock<bool>>,
503 #[cfg(feature = "bft")]
507 bft_manager: Option<Arc<bft_consensus::BftConsensusManager>>,
508}
509
510impl ClusterNode {
511 pub async fn new(config: NodeConfig) -> Result<Self> {
513 if config.data_dir.is_empty() {
515 return Err(ClusterError::Config(
516 "Data directory cannot be empty".to_string(),
517 ));
518 }
519
520 tokio::fs::create_dir_all(&config.data_dir)
522 .await
523 .map_err(|e| ClusterError::Other(format!("Failed to create data directory: {e}")))?;
524
525 #[cfg(feature = "raft")]
532 let consensus = ConsensusManager::new(config.node_id, config.peers.clone())
533 .with_raft_network(config.address, config.peer_addresses.clone());
534 #[cfg(not(feature = "raft"))]
535 let consensus = ConsensusManager::new(config.node_id, config.peers.clone());
536
537 let discovery_config = config.discovery.clone().unwrap_or_default();
539 let discovery = DiscoveryService::new(config.node_id, config.address, discovery_config);
540
541 let replication_strategy = config.replication_strategy.clone().unwrap_or_default();
543 let replication = ReplicationManager::new(replication_strategy, config.node_id);
544
545 let query_executor = DistributedQueryExecutor::new(config.node_id);
547
548 let default_resolution_strategy = if let Some(region_config) = &config.region_config {
550 region_config.conflict_resolution_strategy.clone()
551 } else {
552 ResolutionStrategy::LastWriterWins
553 };
554 let conflict_resolver = Arc::new(ConflictResolver::new(default_resolution_strategy));
555
556 let mut vector_clock = VectorClock::new();
558 vector_clock.increment(config.node_id);
559 let local_vector_clock = Arc::new(RwLock::new(vector_clock));
560
561 let region_manager = if let Some(region_config) = &config.region_config {
563 let manager = Arc::new(RegionManager::new(
564 region_config.region_id.clone(),
565 region_config.availability_zone_id.clone(),
566 region_config.consensus_strategy.clone(),
567 region_config.replication_strategy.clone(),
568 ));
569
570 manager
572 .initialize(region_config.regions.clone())
573 .await
574 .map_err(|e| {
575 ClusterError::Other(format!("Failed to initialize region manager: {e}"))
576 })?;
577
578 manager
580 .register_node(
581 config.node_id,
582 region_config.region_id.clone(),
583 region_config.availability_zone_id.clone(),
584 region_config.data_center.clone(),
585 region_config.rack.clone(),
586 )
587 .await
588 .map_err(|e| {
589 ClusterError::Other(format!("Failed to register node in region manager: {e}"))
590 })?;
591
592 Some(manager)
593 } else {
594 None
595 };
596
597 let edge_manager = if let Some(region_config) = &config.region_config {
599 if let Some(edge_config) = ®ion_config.edge_config {
600 if edge_config.enabled {
601 let manager = Arc::new(EdgeComputingManager::new());
602
603 manager
605 .register_device(edge_config.device_profile.clone())
606 .await
607 .map_err(|e| {
608 ClusterError::Other(format!("Failed to register edge device: {e}"))
609 })?;
610
611 Some(manager)
612 } else {
613 None
614 }
615 } else {
616 None
617 }
618 } else {
619 None
620 };
621
622 Ok(Self {
623 config,
624 consensus,
625 discovery,
626 replication,
627 query_executor,
628 region_manager,
629 conflict_resolver,
630 edge_manager,
631 local_vector_clock,
632 running: Arc::new(RwLock::new(false)),
633 byzantine_mode: Arc::new(RwLock::new(false)),
634 network_isolated: Arc::new(RwLock::new(false)),
635 #[cfg(feature = "bft")]
636 bft_manager: None,
637 })
638 }
639
640 #[cfg(feature = "bft")]
643 pub fn bft_manager(&self) -> Option<&Arc<bft_consensus::BftConsensusManager>> {
644 self.bft_manager.as_ref()
645 }
646
647 #[cfg(feature = "bft")]
652 async fn start_bft_consensus(&mut self) -> Result<()> {
653 use crate::bft_consensus::BftConsensusManager;
654 use crate::network::NetworkConfig;
655 use crate::storage::{PersistentStorage, StorageConfig};
656
657 let storage_config = StorageConfig {
658 data_dir: self.config.data_dir.clone(),
659 ..StorageConfig::default()
660 };
661 let storage = Arc::new(
662 PersistentStorage::new(self.config.node_id, storage_config)
663 .await
664 .map_err(|e| {
665 ClusterError::Storage(format!("failed to open BFT storage backend: {e}"))
666 })?,
667 );
668
669 let peers: Vec<String> = self.config.peers.iter().map(|p| p.to_string()).collect();
670 let manager = BftConsensusManager::new(
671 self.config.node_id.to_string(),
672 peers,
673 storage,
674 NetworkConfig::default(),
675 )
676 .await?;
677 manager.start().await?;
678
679 self.bft_manager = Some(Arc::new(manager));
680 Ok(())
681 }
682
683 pub async fn start(&mut self) -> Result<()> {
685 {
686 let mut running = self.running.write().await;
687 if *running {
688 return Ok(());
689 }
690 *running = true;
691 }
692
693 if self.config.use_bft {
698 #[cfg(feature = "bft")]
699 {
700 self.start_bft_consensus().await?;
701 tracing::info!(
702 "Cluster node {} started in Byzantine fault-tolerant mode",
703 self.config.node_id
704 );
705 return Ok(());
706 }
707 #[cfg(not(feature = "bft"))]
708 {
709 let mut running = self.running.write().await;
710 *running = false;
711 return Err(ClusterError::Config(format!(
712 "node {} requested Byzantine fault tolerance (use_bft = true) but this build \
713 was compiled without the 'bft' feature; refusing to silently fall back to \
714 Raft",
715 self.config.node_id
716 )));
717 }
718 }
719
720 tracing::info!(
721 "Starting cluster node {} at {} with {} peers",
722 self.config.node_id,
723 self.config.address,
724 self.config.peers.len()
725 );
726
727 self.discovery
729 .start()
730 .await
731 .map_err(|e| ClusterError::Other(format!("Failed to start discovery service: {e}")))?;
732
733 let discovered_nodes = self
735 .discovery
736 .discover_nodes()
737 .await
738 .map_err(|e| ClusterError::Other(format!("Failed to discover nodes: {e}")))?;
739
740 for node in discovered_nodes {
742 if node.node_id != self.config.node_id {
743 self.replication
744 .add_replica(node.node_id, node.address.to_string());
745 self.query_executor.add_node(node.node_id).await;
746 }
747 }
748
749 self.consensus
751 .init()
752 .await
753 .map_err(|e| ClusterError::Other(format!("Failed to initialize consensus: {e}")))?;
754
755 tracing::info!("Cluster node {} started successfully", self.config.node_id);
756
757 self.start_background_tasks().await;
759
760 Ok(())
761 }
762
763 pub async fn stop(&mut self) -> Result<()> {
772 let mut running = self.running.write().await;
773 if !*running {
774 return Ok(());
775 }
776
777 tracing::info!("Stopping cluster node {}", self.config.node_id);
778
779 self.discovery
781 .stop()
782 .await
783 .map_err(|e| ClusterError::Other(format!("Failed to stop discovery service: {e}")))?;
784
785 self.consensus
789 .stop_raft()
790 .await
791 .map_err(|e| ClusterError::Other(format!("Failed to stop consensus: {e}")))?;
792
793 *running = false;
794
795 tracing::info!("Cluster node {} stopped", self.config.node_id);
796
797 Ok(())
798 }
799
800 pub async fn is_leader(&self) -> bool {
802 self.consensus.is_leader().await
803 }
804
805 pub async fn current_term(&self) -> u64 {
807 self.consensus.current_term().await
808 }
809
810 pub async fn insert_triple(
812 &self,
813 subject: &str,
814 predicate: &str,
815 object: &str,
816 ) -> Result<RdfResponse> {
817 if !self.is_leader().await {
818 return Err(ClusterError::NotLeader);
819 }
820
821 let response = self
822 .consensus
823 .insert_triple(
824 subject.to_string(),
825 predicate.to_string(),
826 object.to_string(),
827 )
828 .await?;
829
830 Ok(response)
831 }
832
833 pub async fn delete_triple(
835 &self,
836 subject: &str,
837 predicate: &str,
838 object: &str,
839 ) -> Result<RdfResponse> {
840 if !self.is_leader().await {
841 return Err(ClusterError::NotLeader);
842 }
843
844 let response = self
845 .consensus
846 .delete_triple(
847 subject.to_string(),
848 predicate.to_string(),
849 object.to_string(),
850 )
851 .await?;
852
853 Ok(response)
854 }
855
856 pub async fn clear_store(&self) -> Result<RdfResponse> {
858 if !self.is_leader().await {
859 return Err(ClusterError::NotLeader);
860 }
861
862 let response = self.consensus.clear_store().await?;
863 Ok(response)
864 }
865
866 pub async fn begin_transaction(&self) -> Result<String> {
868 if !self.is_leader().await {
869 return Err(ClusterError::NotLeader);
870 }
871
872 let tx_id = uuid::Uuid::new_v4().to_string();
873 let _response = self.consensus.begin_transaction(tx_id.clone()).await?;
874
875 Ok(tx_id)
876 }
877
878 pub async fn commit_transaction(&self, tx_id: &str) -> Result<RdfResponse> {
880 if !self.is_leader().await {
881 return Err(ClusterError::NotLeader);
882 }
883
884 let response = self.consensus.commit_transaction(tx_id.to_string()).await?;
885 Ok(response)
886 }
887
888 pub async fn rollback_transaction(&self, tx_id: &str) -> Result<RdfResponse> {
890 if !self.is_leader().await {
891 return Err(ClusterError::NotLeader);
892 }
893
894 let response = self
895 .consensus
896 .rollback_transaction(tx_id.to_string())
897 .await?;
898 Ok(response)
899 }
900
901 pub async fn query_triples(
903 &self,
904 subject: Option<&str>,
905 predicate: Option<&str>,
906 object: Option<&str>,
907 ) -> Vec<(String, String, String)> {
908 self.consensus.query(subject, predicate, object).await
909 }
910
911 pub async fn query_sparql(&self, sparql: &str) -> Result<Vec<String>> {
913 let bindings = self
914 .query_executor
915 .execute_query(sparql)
916 .await
917 .map_err(|e| ClusterError::Other(format!("Query execution failed: {e}")))?;
918
919 let results = bindings
921 .into_iter()
922 .map(|binding| {
923 let vars: Vec<String> = binding
924 .variables
925 .into_iter()
926 .map(|(var, val)| format!("{var}: {val}"))
927 .collect();
928 vars.join(", ")
929 })
930 .collect();
931
932 Ok(results)
933 }
934
935 pub async fn query_sparql_bindings(&self, sparql: &str) -> Result<Vec<ResultBinding>> {
937 self.query_executor
938 .execute_query(sparql)
939 .await
940 .map_err(|e| ClusterError::Other(format!("Query execution failed: {e}")))
941 }
942
943 pub async fn get_query_statistics(
945 &self,
946 ) -> Result<std::collections::HashMap<String, distributed_query::QueryStats>> {
947 Ok(self.query_executor.get_statistics().await)
948 }
949
950 pub async fn clear_query_cache(&self) -> Result<()> {
952 self.query_executor.clear_cache().await;
953 Ok(())
954 }
955
956 pub async fn len(&self) -> usize {
958 self.consensus.len().await
959 }
960
961 pub async fn is_empty(&self) -> bool {
963 self.consensus.is_empty().await
964 }
965
966 pub async fn add_cluster_node(
968 &mut self,
969 node_id: OxirsNodeId,
970 address: SocketAddr,
971 ) -> Result<()> {
972 if node_id == self.config.node_id {
973 return Err(ClusterError::Config(
974 "Cannot add self to cluster".to_string(),
975 ));
976 }
977
978 self.config.add_peer(node_id);
980
981 let node_info = NodeInfo::new(node_id, address);
983 self.discovery.add_node(node_info);
984
985 self.replication.add_replica(node_id, address.to_string());
987
988 self.query_executor.add_node(node_id).await;
990
991 self.consensus.add_peer(node_id);
993
994 tracing::info!("Added node {} at {} to cluster", node_id, address);
995
996 Ok(())
997 }
998
999 pub async fn remove_cluster_node(&mut self, node_id: OxirsNodeId) -> Result<()> {
1001 if node_id == self.config.node_id {
1002 return Err(ClusterError::Config(
1003 "Cannot remove self from cluster".to_string(),
1004 ));
1005 }
1006
1007 self.config.peers.retain(|&id| id != node_id);
1009
1010 self.discovery.remove_node(node_id);
1012
1013 self.replication.remove_replica(node_id);
1015
1016 self.query_executor.remove_node(node_id).await;
1018
1019 self.consensus.remove_peer(node_id);
1021
1022 tracing::info!("Removed node {} from cluster", node_id);
1023
1024 Ok(())
1025 }
1026
1027 pub async fn get_status(&self) -> ClusterStatus {
1029 let consensus_status = self.consensus.get_status().await;
1030 let discovery_stats = self.discovery.get_stats().clone();
1031 let replication_stats = self.replication.get_stats().clone();
1032
1033 let region_status = if let Some(region_manager) = &self.region_manager {
1035 let region_id = region_manager.get_local_region().to_string();
1036 let availability_zone_id = region_manager.get_local_availability_zone().to_string();
1037 let regional_peers = region_manager.get_nodes_in_region(®ion_id).await;
1038 let topology = region_manager.get_topology().await;
1039 let monitoring_active = region_manager.is_monitoring_active().await;
1040
1041 Some(RegionStatus {
1042 region_id,
1043 availability_zone_id,
1044 regional_peer_count: regional_peers.len(),
1045 total_regions: topology.regions.len(),
1046 monitoring_active,
1047 })
1048 } else {
1049 None
1050 };
1051
1052 ClusterStatus {
1053 node_id: self.config.node_id,
1054 address: self.config.address,
1055 is_leader: consensus_status.is_leader,
1056 current_term: consensus_status.current_term,
1057 peer_count: consensus_status.peer_count,
1058 triple_count: consensus_status.triple_count,
1059 discovery_stats,
1060 replication_stats,
1061 is_running: *self.running.read().await,
1062 region_status,
1063 }
1064 }
1065
1066 async fn start_background_tasks(&mut self) {
1068 let running = Arc::clone(&self.running);
1069
1070 let discovery_config = self.config.discovery.clone().unwrap_or_default();
1072 let mut discovery_clone =
1073 DiscoveryService::new(self.config.node_id, self.config.address, discovery_config);
1074
1075 tokio::spawn(async move {
1076 while *running.read().await {
1077 discovery_clone.run_periodic_tasks().await;
1078 tokio::time::sleep(std::time::Duration::from_secs(1)).await;
1079 }
1080 });
1081
1082 let mut replication_clone = ReplicationManager::with_raft_consensus(self.config.node_id);
1084 let running_clone = Arc::clone(&self.running);
1085
1086 tokio::spawn(async move {
1087 if *running_clone.read().await {
1088 replication_clone.run_maintenance().await; }
1090 });
1091 }
1092
1093 pub async fn add_node_with_consensus(
1095 &mut self,
1096 node_id: OxirsNodeId,
1097 address: SocketAddr,
1098 ) -> Result<()> {
1099 self.consensus
1100 .add_node_with_consensus(node_id, address.to_string())
1101 .await
1102 .map_err(|e| {
1103 ClusterError::Other(format!("Failed to add node through consensus: {e}"))
1104 })?;
1105
1106 self.config.add_peer(node_id);
1108
1109 let node_info = NodeInfo::new(node_id, address);
1111 self.discovery.add_node(node_info);
1112 self.replication.add_replica(node_id, address.to_string());
1113 self.query_executor.add_node(node_id).await;
1114
1115 Ok(())
1116 }
1117
1118 pub async fn remove_node_with_consensus(&mut self, node_id: OxirsNodeId) -> Result<()> {
1120 self.consensus
1121 .remove_node_with_consensus(node_id)
1122 .await
1123 .map_err(|e| {
1124 ClusterError::Other(format!("Failed to remove node through consensus: {e}"))
1125 })?;
1126
1127 self.config.peers.retain(|&id| id != node_id);
1129
1130 self.discovery.remove_node(node_id);
1132 self.replication.remove_replica(node_id);
1133 self.query_executor.remove_node(node_id).await;
1134
1135 Ok(())
1136 }
1137
1138 pub async fn graceful_shutdown(&mut self) -> Result<()> {
1140 tracing::info!(
1141 "Initiating graceful shutdown of cluster node {}",
1142 self.config.node_id
1143 );
1144
1145 {
1147 let mut running = self.running.write().await;
1148 *running = false;
1149 }
1150
1151 self.consensus
1153 .graceful_shutdown()
1154 .await
1155 .map_err(|e| ClusterError::Other(format!("Failed to shutdown consensus: {e}")))?;
1156
1157 self.discovery
1159 .stop()
1160 .await
1161 .map_err(|e| ClusterError::Other(format!("Failed to stop discovery: {e}")))?;
1162
1163 tracing::info!("Cluster node {} gracefully shutdown", self.config.node_id);
1164 Ok(())
1165 }
1166
1167 pub async fn transfer_leadership(&mut self, target_node: OxirsNodeId) -> Result<()> {
1169 if !self.config.peers.contains(&target_node) {
1170 return Err(ClusterError::Config(format!(
1171 "Target node {target_node} not in cluster"
1172 )));
1173 }
1174
1175 self.consensus
1176 .transfer_leadership(target_node)
1177 .await
1178 .map_err(|e| ClusterError::Other(format!("Failed to transfer leadership: {e}")))?;
1179
1180 Ok(())
1181 }
1182
1183 pub async fn force_evict_node(&mut self, node_id: OxirsNodeId) -> Result<()> {
1185 self.consensus
1186 .force_evict_node(node_id)
1187 .await
1188 .map_err(|e| ClusterError::Other(format!("Failed to force evict node: {e}")))?;
1189
1190 self.config.peers.retain(|&id| id != node_id);
1192 self.discovery.remove_node(node_id);
1193 self.replication.remove_replica(node_id);
1194 self.query_executor.remove_node(node_id).await;
1195
1196 Ok(())
1197 }
1198
1199 pub async fn check_cluster_health(&self) -> Result<Vec<consensus::NodeHealthStatus>> {
1201 self.consensus
1202 .check_peer_health()
1203 .await
1204 .map_err(|e| ClusterError::Other(format!("Failed to check cluster health: {e}")))
1205 }
1206
1207 pub async fn attempt_recovery(&mut self) -> Result<()> {
1209 self.consensus
1210 .attempt_recovery()
1211 .await
1212 .map_err(|e| ClusterError::Other(format!("Failed to recover cluster: {e}")))?;
1213
1214 tracing::info!(
1215 "Cluster recovery completed for node {}",
1216 self.config.node_id
1217 );
1218 Ok(())
1219 }
1220
1221 pub fn id(&self) -> OxirsNodeId {
1223 self.config.node_id
1224 }
1225
1226 pub async fn count_triples(&self) -> Result<usize> {
1228 Ok(self.len().await)
1229 }
1230
1231 pub async fn is_active(&self) -> Result<bool> {
1233 Ok(*self.running.read().await && !*self.network_isolated.read().await)
1234 }
1235
1236 pub async fn isolate_network(&self) -> Result<()> {
1238 let mut isolated = self.network_isolated.write().await;
1239 *isolated = true;
1240 tracing::info!("Node {} network isolated", self.config.node_id);
1241 Ok(())
1242 }
1243
1244 pub async fn restore_network(&self) -> Result<()> {
1246 let mut isolated = self.network_isolated.write().await;
1247 *isolated = false;
1248 tracing::info!("Node {} network restored", self.config.node_id);
1249 Ok(())
1250 }
1251
1252 pub async fn enable_byzantine_mode(&self) -> Result<()> {
1254 let mut byzantine = self.byzantine_mode.write().await;
1255 *byzantine = true;
1256 tracing::info!("Node {} Byzantine mode enabled", self.config.node_id);
1257 Ok(())
1258 }
1259
1260 pub async fn is_byzantine(&self) -> Result<bool> {
1262 Ok(*self.byzantine_mode.read().await)
1263 }
1264
1265 pub fn region_manager(&self) -> Option<&Arc<RegionManager>> {
1267 self.region_manager.as_ref()
1268 }
1269
1270 pub fn is_multi_region_enabled(&self) -> bool {
1272 self.region_manager.is_some()
1273 }
1274
1275 pub fn get_region_id(&self) -> Option<String> {
1277 self.region_manager
1278 .as_ref()
1279 .map(|rm| rm.get_local_region().to_string())
1280 }
1281
1282 pub fn get_availability_zone_id(&self) -> Option<String> {
1284 self.region_manager
1285 .as_ref()
1286 .map(|rm| rm.get_local_availability_zone().to_string())
1287 }
1288
1289 pub async fn get_regional_peers(&self) -> Result<Vec<OxirsNodeId>> {
1291 if let Some(region_manager) = &self.region_manager {
1292 let region_id = region_manager.get_local_region();
1293 Ok(region_manager.get_nodes_in_region(region_id).await)
1294 } else {
1295 Err(ClusterError::Config(
1296 "Multi-region not configured".to_string(),
1297 ))
1298 }
1299 }
1300
1301 pub async fn get_regional_leader_candidates(&self) -> Result<Vec<OxirsNodeId>> {
1303 if let Some(region_manager) = &self.region_manager {
1304 let region_id = region_manager.get_local_region();
1305 Ok(region_manager.get_leader_candidates(region_id).await)
1306 } else {
1307 Ok(self.config.peers.clone())
1309 }
1310 }
1311
1312 pub async fn get_cross_region_replication_targets(&self) -> Result<Vec<String>> {
1314 if let Some(region_manager) = &self.region_manager {
1315 let region_id = region_manager.get_local_region();
1316 region_manager
1317 .calculate_replication_targets(region_id)
1318 .await
1319 .map_err(|e| {
1320 ClusterError::Other(format!("Failed to calculate replication targets: {e}"))
1321 })
1322 } else {
1323 Ok(Vec::new())
1324 }
1325 }
1326
1327 pub async fn monitor_region_latencies(&self) -> Result<()> {
1329 if let Some(region_manager) = &self.region_manager {
1330 region_manager.monitor_latencies().await.map_err(|e| {
1331 ClusterError::Other(format!("Failed to monitor region latencies: {e}"))
1332 })
1333 } else {
1334 Ok(())
1335 }
1336 }
1337
1338 pub async fn get_region_health(&self, region_id: &str) -> Result<region_manager::RegionHealth> {
1340 if let Some(region_manager) = &self.region_manager {
1341 region_manager
1342 .get_region_health(region_id)
1343 .await
1344 .map_err(|e| ClusterError::Other(format!("Failed to get region health: {e}")))
1345 } else {
1346 Err(ClusterError::Config(
1347 "Multi-region not configured".to_string(),
1348 ))
1349 }
1350 }
1351
1352 pub async fn perform_region_failover(
1354 &self,
1355 failed_region: &str,
1356 target_region: &str,
1357 ) -> Result<()> {
1358 if let Some(region_manager) = &self.region_manager {
1359 region_manager
1360 .perform_region_failover(failed_region, target_region)
1361 .await
1362 .map_err(|e| ClusterError::Other(format!("Failed to perform region failover: {e}")))
1363 } else {
1364 Err(ClusterError::Config(
1365 "Multi-region not configured".to_string(),
1366 ))
1367 }
1368 }
1369
1370 pub async fn get_region_topology(&self) -> Result<region_manager::RegionTopology> {
1372 if let Some(region_manager) = &self.region_manager {
1373 Ok(region_manager.get_topology().await)
1374 } else {
1375 Err(ClusterError::Config(
1376 "Multi-region not configured".to_string(),
1377 ))
1378 }
1379 }
1380
1381 pub async fn add_node_to_region(
1383 &self,
1384 node_id: OxirsNodeId,
1385 region_id: String,
1386 availability_zone_id: String,
1387 data_center: Option<String>,
1388 rack: Option<String>,
1389 ) -> Result<()> {
1390 if let Some(region_manager) = &self.region_manager {
1391 region_manager
1392 .register_node(node_id, region_id, availability_zone_id, data_center, rack)
1393 .await
1394 .map_err(|e| ClusterError::Other(format!("Failed to add node to region: {e}")))
1395 } else {
1396 Err(ClusterError::Config(
1397 "Multi-region not configured".to_string(),
1398 ))
1399 }
1400 }
1401
1402 pub fn conflict_resolver(&self) -> &Arc<ConflictResolver> {
1404 &self.conflict_resolver
1405 }
1406
1407 pub async fn get_vector_clock(&self) -> VectorClock {
1409 self.local_vector_clock.read().await.clone()
1410 }
1411
1412 pub async fn update_vector_clock(&self, received_clock: &VectorClock) {
1414 let mut clock = self.local_vector_clock.write().await;
1415 clock.update(received_clock);
1416 clock.increment(self.config.node_id);
1417 }
1418
1419 pub async fn create_timestamped_operation(
1421 &self,
1422 operation: conflict_resolution::RdfOperation,
1423 priority: u32,
1424 ) -> TimestampedOperation {
1425 let mut clock = self.local_vector_clock.write().await;
1426 clock.increment(self.config.node_id);
1427
1428 TimestampedOperation {
1429 operation_id: uuid::Uuid::new_v4().to_string(),
1430 origin_node: self.config.node_id,
1431 vector_clock: clock.clone(),
1432 physical_time: std::time::SystemTime::now(),
1433 operation,
1434 priority,
1435 }
1436 }
1437
1438 pub async fn detect_operation_conflicts(
1440 &self,
1441 operations: &[TimestampedOperation],
1442 ) -> Result<Vec<conflict_resolution::ConflictType>> {
1443 self.conflict_resolver
1444 .detect_conflicts(operations)
1445 .await
1446 .map_err(|e| ClusterError::Other(format!("Failed to detect conflicts: {e}")))
1447 }
1448
1449 pub async fn resolve_operation_conflicts(
1451 &self,
1452 conflicts: &[conflict_resolution::ConflictType],
1453 ) -> Result<Vec<conflict_resolution::ResolutionResult>> {
1454 self.conflict_resolver
1455 .resolve_conflicts(conflicts)
1456 .await
1457 .map_err(|e| ClusterError::Other(format!("Failed to resolve conflicts: {e}")))
1458 }
1459
1460 pub async fn submit_conflict_aware_operation(
1462 &self,
1463 operation: conflict_resolution::RdfOperation,
1464 priority: u32,
1465 ) -> Result<RdfResponse> {
1466 let _timestamped_op = self
1468 .create_timestamped_operation(operation.clone(), priority)
1469 .await;
1470
1471 match operation {
1474 conflict_resolution::RdfOperation::Insert {
1475 subject,
1476 predicate,
1477 object,
1478 ..
1479 } => self.insert_triple(&subject, &predicate, &object).await,
1480 conflict_resolution::RdfOperation::Delete {
1481 subject,
1482 predicate,
1483 object,
1484 ..
1485 } => self.delete_triple(&subject, &predicate, &object).await,
1486 conflict_resolution::RdfOperation::Clear { .. } => self.clear_store().await,
1487 conflict_resolution::RdfOperation::Update {
1488 old_triple,
1489 new_triple,
1490 ..
1491 } => {
1492 let _delete_result = self
1494 .delete_triple(&old_triple.0, &old_triple.1, &old_triple.2)
1495 .await?;
1496 self.insert_triple(&new_triple.0, &new_triple.1, &new_triple.2)
1497 .await
1498 }
1499 conflict_resolution::RdfOperation::Batch { operations: _ } => {
1500 Ok(RdfResponse::Success)
1505 }
1506 }
1507 }
1508
1509 pub async fn get_conflict_resolution_statistics(
1511 &self,
1512 ) -> conflict_resolution::ResolutionStatistics {
1513 self.conflict_resolver.get_statistics().await
1514 }
1515}
1516
1517#[derive(Debug, Clone)]
1519pub struct ClusterStatus {
1520 pub node_id: OxirsNodeId,
1522 pub address: SocketAddr,
1524 pub is_leader: bool,
1526 pub current_term: u64,
1528 pub peer_count: usize,
1530 pub triple_count: usize,
1532 pub discovery_stats: discovery::DiscoveryStats,
1534 pub replication_stats: ReplicationStats,
1536 pub is_running: bool,
1538 pub region_status: Option<RegionStatus>,
1540}
1541
1542#[derive(Debug, Clone)]
1544pub struct RegionStatus {
1545 pub region_id: String,
1547 pub availability_zone_id: String,
1549 pub regional_peer_count: usize,
1551 pub total_regions: usize,
1553 pub monitoring_active: bool,
1555}
1556
1557pub struct DistributedStore {
1559 node: ClusterNode,
1560}
1561
1562impl DistributedStore {
1563 pub async fn new(config: NodeConfig) -> Result<Self> {
1565 let node = ClusterNode::new(config).await?;
1566 Ok(Self { node })
1567 }
1568
1569 pub async fn start(&mut self) -> Result<()> {
1571 self.node.start().await
1572 }
1573
1574 pub async fn stop(&mut self) -> Result<()> {
1576 self.node.stop().await
1577 }
1578
1579 pub async fn insert_triple(
1581 &mut self,
1582 subject: &str,
1583 predicate: &str,
1584 object: &str,
1585 ) -> Result<()> {
1586 let _response = self.node.insert_triple(subject, predicate, object).await?;
1587 Ok(())
1588 }
1589
1590 pub async fn query_sparql(&self, sparql: &str) -> Result<Vec<String>> {
1592 self.node.query_sparql(sparql).await
1593 }
1594
1595 pub async fn query_pattern(
1597 &self,
1598 subject: Option<&str>,
1599 predicate: Option<&str>,
1600 object: Option<&str>,
1601 ) -> Vec<(String, String, String)> {
1602 self.node.query_triples(subject, predicate, object).await
1603 }
1604
1605 pub async fn get_status(&self) -> ClusterStatus {
1607 self.node.get_status().await
1608 }
1609}
1610
1611pub use consensus::ConsensusError;
1613pub use discovery::DiscoveryError;
1614pub use replication::ReplicationError;
1615
1616#[cfg(test)]
1617mod tests {
1618 use super::*;
1619 use std::net::{IpAddr, Ipv4Addr};
1620
1621 #[tokio::test]
1622 async fn test_node_config_creation() {
1623 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
1624 let config = NodeConfig::new(1, addr);
1625
1626 assert_eq!(config.node_id, 1);
1627 assert_eq!(config.address, addr);
1628 assert_eq!(config.data_dir, "./data/node-1");
1629 assert!(config.peers.is_empty());
1630 assert!(config.discovery.is_some());
1631 assert!(config.replication_strategy.is_some());
1632 assert!(config.region_config.is_none());
1633 }
1634
1635 #[tokio::test]
1636 async fn test_node_config_add_peer() {
1637 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
1638 let mut config = NodeConfig::new(1, addr);
1639
1640 config.add_peer(2);
1641 config.add_peer(3);
1642 config.add_peer(2); assert_eq!(config.peers, vec![2, 3]);
1645 }
1646
1647 #[tokio::test]
1648 async fn test_node_config_no_self_peer() {
1649 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
1650 let mut config = NodeConfig::new(1, addr);
1651
1652 config.add_peer(1); assert!(config.peers.is_empty());
1655 }
1656
1657 #[tokio::test]
1658 async fn test_cluster_node_creation() {
1659 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
1660 let config = NodeConfig::new(1, addr);
1661
1662 let node = ClusterNode::new(config).await;
1663 assert!(node.is_ok());
1664
1665 let node = node.unwrap();
1666 assert_eq!(node.config.node_id, 1);
1667 assert_eq!(node.config.address, addr);
1668 }
1669
1670 #[tokio::test]
1671 async fn test_cluster_node_empty_data_dir_error() {
1672 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
1673 let mut config = NodeConfig::new(1, addr);
1674 config.data_dir = String::new();
1675
1676 let result = ClusterNode::new(config).await;
1677 assert!(result.is_err());
1678 if let Err(e) = result {
1679 assert!(e.to_string().contains("Data directory cannot be empty"));
1680 }
1681 }
1682
1683 #[tokio::test]
1684 async fn test_distributed_store_creation() {
1685 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
1686 let config = NodeConfig::new(1, addr);
1687
1688 let store = DistributedStore::new(config).await;
1689 assert!(store.is_ok());
1690 }
1691
1692 #[test]
1693 fn test_cluster_error_types() {
1694 let err = ClusterError::Config("test error".to_string());
1695 assert!(err.to_string().contains("Configuration error: test error"));
1696
1697 let err = ClusterError::NotLeader;
1698 assert_eq!(err.to_string(), "Not the leader node");
1699
1700 let err = ClusterError::Network("connection failed".to_string());
1701 assert!(err.to_string().contains("Network error: connection failed"));
1702 }
1703}