-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
add condition router, add tag router, use nacos as router config center
- Loading branch information
1 parent
df0e0e5
commit c07b96d
Showing
22 changed files
with
1,084 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,4 +21,5 @@ pub mod config; | |
pub mod protocol; | ||
pub mod provider; | ||
pub mod registry; | ||
pub mod router; | ||
pub mod service; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] | ||
pub struct ConditionRouterConfig { | ||
pub scope: String, | ||
pub force: bool, | ||
pub runtime: bool, | ||
pub enabled: bool, | ||
pub key: String, | ||
pub conditions: Vec<String>, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)] | ||
pub struct TagRouterConfig { | ||
pub force: bool, | ||
pub enabled: bool, | ||
pub key: String, | ||
pub tags: Vec<Tag>, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Clone, PartialEq, Default, Debug)] | ||
pub struct ConsumerConfig { | ||
pub service: String, | ||
pub url: String, | ||
pub protocol: String, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)] | ||
pub struct Tag { | ||
pub name: String, | ||
pub matches: Vec<TagMatchRule>, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)] | ||
pub struct TagMatchRule { | ||
pub key: String, | ||
pub value: String, | ||
} | ||
|
||
impl ConditionRouterConfig { | ||
pub fn new(config: &String) -> Self { | ||
serde_yaml::from_str(config).expect("parse error") | ||
} | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] | ||
pub struct EnableAuth { | ||
pub auth_username: String, | ||
pub auth_password: String, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] | ||
pub struct NacosConfig { | ||
pub addr: String, | ||
pub namespace: String, | ||
pub app: String, | ||
pub enable_auth: Option<EnableAuth>, | ||
pub enable_auth_plugin_http: Option<bool>, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] | ||
pub struct RouterConfig { | ||
pub consumer: Option<Vec<ConsumerConfig>>, | ||
pub nacos: Option<NacosConfig>, | ||
pub conditions: Option<Vec<ConditionRouterConfig>>, | ||
pub tags: Option<TagRouterConfig>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use crate::{ | ||
cluster::router::{condition::single_router::ConditionSingleRouter, Router}, | ||
codegen::RpcInvocation, | ||
}; | ||
use dubbo_base::Url; | ||
use std::{ | ||
fmt::Debug, | ||
sync::{Arc, RwLock}, | ||
}; | ||
|
||
#[derive(Default, Debug, Clone)] | ||
pub struct ConditionRouter { | ||
//condition router for service scope | ||
pub service_routers: Option<Arc<RwLock<ConditionSingleRouters>>>, | ||
//condition router for application scope | ||
pub application_routers: Option<Arc<RwLock<ConditionSingleRouters>>>, | ||
} | ||
|
||
impl Router for ConditionRouter { | ||
fn route(&self, invokers: Vec<Url>, url: Url, invo: Arc<RpcInvocation>) -> Vec<Url> { | ||
let mut invokers_result = invokers.clone(); | ||
if let Some(routers) = self.application_routers.clone() { | ||
for router in &routers.read().unwrap().routers { | ||
invokers_result = router.route(invokers_result, url.clone(), invo.clone()) | ||
} | ||
} | ||
if let Some(routers) = self.service_routers.clone() { | ||
for router in &routers.read().unwrap().routers { | ||
invokers_result = router.route(invokers_result, url.clone(), invo.clone()) | ||
} | ||
} | ||
invokers_result | ||
} | ||
} | ||
|
||
impl ConditionRouter { | ||
pub fn new( | ||
service_routers: Option<Arc<RwLock<ConditionSingleRouters>>>, | ||
application_routers: Option<Arc<RwLock<ConditionSingleRouters>>>, | ||
) -> Self { | ||
Self { | ||
service_routers, | ||
application_routers, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone, Default)] | ||
pub struct ConditionSingleRouters { | ||
pub routers: Vec<ConditionSingleRouter>, | ||
} | ||
|
||
impl ConditionSingleRouters { | ||
pub fn new(routers: Vec<ConditionSingleRouter>) -> Self { | ||
Self { routers } | ||
} | ||
pub fn is_null(&self) -> bool { | ||
self.routers.is_empty() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
use crate::codegen::RpcInvocation; | ||
use regex::Regex; | ||
use std::{collections::HashSet, error::Error, option::Option, sync::Arc}; | ||
|
||
#[derive(Clone, Debug, Default)] | ||
pub struct ConditionMatcher { | ||
_key: String, | ||
matches: HashSet<String>, | ||
mismatches: HashSet<String>, | ||
} | ||
|
||
impl ConditionMatcher { | ||
pub fn new(_key: String) -> Self { | ||
ConditionMatcher { | ||
_key, | ||
matches: HashSet::new(), | ||
mismatches: HashSet::new(), | ||
} | ||
} | ||
|
||
pub fn is_match( | ||
&self, | ||
value: Option<String>, | ||
invocation: Arc<RpcInvocation>, | ||
_is_when: bool, | ||
) -> Result<bool, Box<dyn Error>> { | ||
match value { | ||
None => { | ||
// if key does not present in whichever of url, invocation or attachment based on the matcher type, then return false. | ||
Ok(false) | ||
} | ||
Some(val) => { | ||
if !self.matches.is_empty() && self.mismatches.is_empty() { | ||
for match_ in self.matches.iter() { | ||
if self.do_pattern_match(match_, &val, invocation.clone())? { | ||
return Ok(true); | ||
} | ||
} | ||
Ok(false) | ||
} else if !self.mismatches.is_empty() && self.matches.is_empty() { | ||
for mismatch in self.mismatches.iter() { | ||
if self.do_pattern_match(mismatch, &val, invocation.clone())? { | ||
return Ok(false); | ||
} | ||
} | ||
Ok(true) | ||
} else if !self.matches.is_empty() && !self.mismatches.is_empty() { | ||
for mismatch in self.mismatches.iter() { | ||
if self.do_pattern_match(mismatch, &val, invocation.clone())? { | ||
return Ok(false); | ||
} | ||
} | ||
for match_ in self.matches.iter() { | ||
if self.do_pattern_match(match_, &val, invocation.clone())? { | ||
return Ok(true); | ||
} | ||
} | ||
Ok(false) | ||
} else { | ||
Ok(false) | ||
} | ||
} | ||
} | ||
} | ||
pub fn get_matches(&mut self) -> &mut HashSet<String> { | ||
&mut self.matches | ||
} | ||
pub fn get_mismatches(&mut self) -> &mut HashSet<String> { | ||
&mut self.mismatches | ||
} | ||
|
||
fn do_pattern_match( | ||
&self, | ||
pattern: &String, | ||
value: &String, | ||
_invocation: Arc<RpcInvocation>, | ||
) -> Result<bool, Box<dyn Error>> { | ||
if pattern.contains("*") { | ||
return Ok(star_matcher(pattern, value)); | ||
} | ||
Ok(pattern.eq(value)) | ||
} | ||
} | ||
|
||
pub fn star_matcher(pattern: &str, input: &str) -> bool { | ||
// 将*替换为任意字符的正则表达式 | ||
let pattern = pattern.replace("*", ".*"); | ||
let regex = Regex::new(&pattern).unwrap(); | ||
regex.is_match(input) | ||
} | ||
|
||
pub fn _range_matcher(val: i32, min: i32, max: i32) -> bool { | ||
min <= val && val <= max | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod condition_router; | ||
pub mod matcher; | ||
pub mod single_router; |
Oops, something went wrong.