|
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