|
1 | 1 | pub mod store { |
2 | | - use code0_flow::flow_store::connection::FlowStore; |
| 2 | + use std::sync::Arc; |
| 3 | + |
| 4 | + use code0_flow::flow_store::service::{FlowStoreService, FlowStoreServiceBase}; |
3 | 5 | use http::request::HttpRequest; |
4 | | - use redis::{AsyncCommands, JsonAsyncCommands}; |
5 | 6 | use regex::Regex; |
6 | | - use tucana::shared::{value::Kind, Flow, Struct}; |
| 7 | + use tokio::sync::Mutex; |
| 8 | + use tucana::shared::{value::Kind, Flow, FlowSetting}; |
7 | 9 |
|
8 | 10 | //The regex is required for later purposes --> resolve the parameter of the url |
9 | 11 | pub struct FlowExistResult { |
10 | 12 | pub flow: Flow, |
11 | 13 | pub regex_pattern: Regex, |
12 | 14 | } |
13 | 15 |
|
14 | | - pub async fn check_flow_exists( |
15 | | - flow_store: &FlowStore, |
16 | | - request: &HttpRequest, |
17 | | - ) -> Option<FlowExistResult> { |
18 | | - let mut store = flow_store.lock().await; |
19 | | - |
20 | | - // Get all keys from Redis |
21 | | - let keys: Vec<String> = store.keys("*").await.unwrap_or_default(); |
22 | | - let mut result: Vec<Flow> = Vec::new(); |
23 | | - |
24 | | - // Retrieve JSON values for each key |
25 | | - for key in keys { |
26 | | - if let Ok(json_value) = store.json_get::<&String, &str, String>(&key, "$").await { |
27 | | - let flow = match serde_json::from_str::<Vec<Flow>>(json_value.as_str()) { |
28 | | - Ok(flow) => flow[0].clone(), |
29 | | - Err(_) => continue, |
30 | | - }; |
31 | | - |
32 | | - result.push(flow); |
| 16 | + fn extract_field(settings: &[FlowSetting], def_key: &str, field_name: &str) -> Option<String> { |
| 17 | + settings.iter().find_map(|setting| { |
| 18 | + let def = setting.definition.as_ref()?; |
| 19 | + if def.key != def_key { |
| 20 | + return None; |
33 | 21 | } |
34 | | - } |
35 | | - |
36 | | - for flow in result { |
37 | | - let mut correct_url = false; |
38 | | - let mut correct_method = false; |
39 | | - let mut flow_regex: Option<Regex> = None; |
40 | | - |
41 | | - for setting in flow.settings.clone() { |
42 | | - let definition = match setting.definition { |
43 | | - Some(definition) => definition, |
44 | | - None => continue, |
45 | | - }; |
46 | | - |
47 | | - if definition.key == "HTTP_METHOD" { |
48 | | - let object: Struct = match setting.object { |
49 | | - Some(object) => object, |
50 | | - None => continue, |
51 | | - }; |
52 | 22 |
|
53 | | - for field in object.fields { |
54 | | - if field.0 == "method" { |
55 | | - if let Some(Kind::StringValue(method)) = field.1.kind { |
56 | | - if method == request.method.to_string() { |
57 | | - correct_method = true; |
58 | | - } |
59 | | - } |
60 | | - } |
| 23 | + let obj = setting.object.as_ref()?; |
| 24 | + obj.fields.iter().find_map(|(k, v)| { |
| 25 | + if k == field_name { |
| 26 | + if let Some(Kind::StringValue(s)) = &v.kind { |
| 27 | + return Some(s.clone()); |
61 | 28 | } |
62 | | - |
63 | | - continue; |
64 | 29 | } |
| 30 | + None |
| 31 | + }) |
| 32 | + }) |
| 33 | + } |
65 | 34 |
|
66 | | - if definition.key == "URL" { |
67 | | - let object: Struct = match setting.object { |
68 | | - Some(object) => object, |
69 | | - None => continue, |
70 | | - }; |
| 35 | + pub async fn check_flow_exists( |
| 36 | + flow_store: Arc<Mutex<FlowStoreService>>, |
| 37 | + request: &HttpRequest, |
| 38 | + ) -> Option<FlowExistResult> { |
| 39 | + let flows = { |
| 40 | + let mut store = flow_store.lock().await; |
| 41 | + let pattern = format!("*::*::{}::{}", request.host, request.method.to_string()); |
| 42 | + let result = store.query_flows(pattern).await; |
| 43 | + |
| 44 | + match result { |
| 45 | + Ok(flows) => flows.flows, |
| 46 | + Err(_) => return None, |
| 47 | + } |
| 48 | + }; |
71 | 49 |
|
72 | | - for field in object.fields { |
73 | | - if field.0 == "url" { |
74 | | - if let Some(Kind::StringValue(regex_str)) = field.1.kind { |
75 | | - let regex = match regex::Regex::new(®ex_str) { |
76 | | - Ok(regex) => regex, |
77 | | - Err(err) => { |
78 | | - log::error!("Failed to compile regex: {}", err); |
79 | | - continue; |
80 | | - } |
81 | | - }; |
| 50 | + for flow in flows { |
| 51 | + let url = extract_field(&flow.settings, "HTTP_URL", "url"); |
82 | 52 |
|
83 | | - if regex.is_match(&request.path) { |
84 | | - correct_url = true; |
85 | | - flow_regex = Some(regex); |
86 | | - } |
87 | | - } |
88 | | - } |
89 | | - } |
| 53 | + let regex_str = match url { |
| 54 | + Some(string) => string, |
| 55 | + None => continue, |
| 56 | + }; |
90 | 57 |
|
| 58 | + let regex = match regex::Regex::new(®ex_str) { |
| 59 | + Ok(regex) => regex, |
| 60 | + Err(err) => { |
| 61 | + log::error!("Failed to compile regex: {}", err); |
91 | 62 | continue; |
92 | 63 | } |
93 | | - } |
94 | | - |
95 | | - if correct_method && correct_url { |
96 | | - let regex_pattern = match flow_regex { |
97 | | - Some(regex) => regex.clone(), |
98 | | - None => continue, |
99 | | - }; |
| 64 | + }; |
100 | 65 |
|
| 66 | + if regex.is_match(&request.path) { |
101 | 67 | return Some(FlowExistResult { |
102 | 68 | flow, |
103 | | - regex_pattern, |
| 69 | + regex_pattern: regex, |
104 | 70 | }); |
105 | 71 | } |
106 | 72 | } |
107 | | - |
108 | 73 | None |
109 | 74 | } |
110 | 75 | } |
0 commit comments