mockforge_http/consistency/
http_adapter.rs1use mockforge_core::consistency::adapters::ProtocolAdapter;
7use mockforge_core::consistency::types::{PersonaProfile, ProtocolState, StateChangeEvent};
8use mockforge_core::consistency::ConsistencyEngine;
9use mockforge_core::protocol_abstraction::Protocol;
10use mockforge_core::Result;
11use std::sync::Arc;
12use tokio::sync::RwLock;
13use tracing::{debug, info, warn};
14
15pub struct HttpAdapter {
20 engine: Arc<ConsistencyEngine>,
22 workspace_personas: Arc<RwLock<std::collections::HashMap<String, Option<PersonaProfile>>>>,
24 workspace_scenarios: Arc<RwLock<std::collections::HashMap<String, Option<String>>>>,
26}
27
28impl HttpAdapter {
29 pub fn new(engine: Arc<ConsistencyEngine>) -> Self {
31 Self {
32 engine,
33 workspace_personas: Arc::new(RwLock::new(std::collections::HashMap::new())),
34 workspace_scenarios: Arc::new(RwLock::new(std::collections::HashMap::new())),
35 }
36 }
37
38 pub async fn get_persona(&self, workspace_id: &str) -> Option<PersonaProfile> {
40 let personas = self.workspace_personas.read().await;
41 personas.get(workspace_id).cloned().flatten()
42 }
43
44 pub async fn get_scenario(&self, workspace_id: &str) -> Option<String> {
46 let scenarios = self.workspace_scenarios.read().await;
47 scenarios.get(workspace_id).cloned().flatten()
48 }
49}
50
51#[async_trait::async_trait]
52impl ProtocolAdapter for HttpAdapter {
53 fn protocol(&self) -> Protocol {
54 Protocol::Http
55 }
56
57 async fn on_state_change(&self, event: &StateChangeEvent) -> Result<()> {
58 match event {
59 StateChangeEvent::PersonaChanged {
60 workspace_id,
61 persona,
62 } => {
63 let mut personas = self.workspace_personas.write().await;
64 personas.insert(workspace_id.clone(), Some(persona.clone()));
65 info!(
66 "HTTP adapter: Updated persona for workspace {} to {}",
67 workspace_id, persona.id
68 );
69 }
70 StateChangeEvent::ScenarioChanged {
71 workspace_id,
72 scenario_id,
73 } => {
74 let mut scenarios = self.workspace_scenarios.write().await;
75 scenarios.insert(workspace_id.clone(), Some(scenario_id.clone()));
76 info!(
77 "HTTP adapter: Updated scenario for workspace {} to {}",
78 workspace_id, scenario_id
79 );
80 }
81 StateChangeEvent::RealityLevelChanged { workspace_id, .. } => {
82 debug!("HTTP adapter: Reality level changed for workspace {}", workspace_id);
83 }
85 StateChangeEvent::RealityRatioChanged { workspace_id, .. } => {
86 debug!("HTTP adapter: Reality ratio changed for workspace {}", workspace_id);
87 }
89 StateChangeEvent::EntityCreated {
90 workspace_id,
91 entity,
92 } => {
93 debug!(
94 "HTTP adapter: Entity created {}:{} for workspace {}",
95 entity.entity_type, entity.entity_id, workspace_id
96 );
97 }
99 StateChangeEvent::EntityUpdated {
100 workspace_id,
101 entity,
102 } => {
103 debug!(
104 "HTTP adapter: Entity updated {}:{} for workspace {}",
105 entity.entity_type, entity.entity_id, workspace_id
106 );
107 }
109 StateChangeEvent::ChaosRuleActivated { workspace_id, rule } => {
110 let rule_name = rule.get("name").and_then(|v| v.as_str()).unwrap_or("unknown");
112 info!(
113 "HTTP adapter: Chaos rule '{}' activated for workspace {}",
114 rule_name, workspace_id
115 );
116 }
118 StateChangeEvent::ChaosRuleDeactivated {
119 workspace_id,
120 rule_name,
121 } => {
122 info!(
123 "HTTP adapter: Chaos rule '{}' deactivated for workspace {}",
124 rule_name, workspace_id
125 );
126 }
128 }
129 Ok(())
130 }
131
132 async fn get_current_state(&self, workspace_id: &str) -> Result<Option<ProtocolState>> {
133 let state = self.engine.get_protocol_state(workspace_id, Protocol::Http).await;
135 Ok(state)
136 }
137
138 async fn apply_persona(&self, workspace_id: &str, persona: &PersonaProfile) -> Result<()> {
139 let mut personas = self.workspace_personas.write().await;
140 personas.insert(workspace_id.to_string(), Some(persona.clone()));
141 info!("HTTP adapter: Applied persona {} to workspace {}", persona.id, workspace_id);
142 Ok(())
143 }
144
145 async fn apply_scenario(&self, workspace_id: &str, scenario_id: &str) -> Result<()> {
146 let mut scenarios = self.workspace_scenarios.write().await;
147 scenarios.insert(workspace_id.to_string(), Some(scenario_id.to_string()));
148 info!("HTTP adapter: Applied scenario {} to workspace {}", scenario_id, workspace_id);
149 Ok(())
150 }
151}