Skip to content

Commit

Permalink
update vo conv to model
Browse files Browse the repository at this point in the history
  • Loading branch information
RWDai committed Nov 16, 2023
1 parent e3b33e5 commit defab1f
Show file tree
Hide file tree
Showing 15 changed files with 191 additions and 109 deletions.
2 changes: 1 addition & 1 deletion admin/src/api/gateway_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl GatewayApi {
let result = GatewayVoService::list(
GatewayQueryDto {
names: names.0.map(|n| n.split(',').map(|n| n.to_string()).collect()),
port: port.0.map(|p| p.parse::<u16>()).transpose().map_err(|e| TardisError::bad_request("bad port format", ""))?,
port: port.0.map(|p| p.parse::<u16>()).transpose().map_err(|_e| TardisError::bad_request("bad port format", ""))?,
hostname: hostname.0,
tls_ids: tls_ids.0.map(|tls_ids| tls_ids.split(',').map(|tls_id| tls_id.to_string()).collect()),
}
Expand Down
4 changes: 2 additions & 2 deletions admin/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ pub async fn get_k8s_client() -> TardisResult<Client> {

/// Convert fuzzy search queries into regular instance
pub fn fuzzy_regex(query: impl AsRef<str>) -> TardisResult<Regex> {
let fuzzy_ = Regex::new(r#"(?<frist>[^\\]?)\*(?<last>\w*)"#)?;
let fuzzy_ = Regex::new(r"(?<frist>[^\\]?)\*(?<last>\w*)")?;
let query = fuzzy_.replace_all(query.as_ref(), |caps: &regex::Captures| format!("{}.*{}", &caps["frist"], &caps["last"]));
Ok(Regex::new(&format!("^{}$", query))?.into())
Ok(Regex::new(&format!("^{}$", query))?)
}

pub fn find_add_delete<T>(new: Vec<T>, old: Vec<T>) -> (Vec<T>, Vec<T>)
Expand Down
5 changes: 1 addition & 4 deletions admin/src/model/add_dto.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use crate::model::vo::gateway_vo::{SgGatewayVo, SgListenerVo};
use crate::model::vo::http_route_vo::{SgHttpRouteRuleVo, SgHttpRouteVo};
use crate::model::vo::plugin_vo::SgFilterVo;
use crate::model::vo::Vo;
use kernel_common::helper::k8s_helper::{format_k8s_obj_unique, get_k8s_obj_unique};
use kernel_common::inner_model::gateway::SgParameters;

use serde::{Deserialize, Serialize};
use serde_json::Value;
use tardis::basic::result::TardisResult;
Expand Down
5 changes: 2 additions & 3 deletions admin/src/model/query_dto.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::helper::fuzzy_regex;
use crate::model::base_dto::TargetRefDTO;
#[cfg(feature = "k8s")]
use crate::model::ToFields;

use tardis::basic::result::TardisResult;
use tardis::regex::Regex;

Expand All @@ -10,6 +8,7 @@ pub trait ToInstance<T: Instance> {
fn to_instance(self) -> TardisResult<T>;
}

#[derive(Default)]
pub struct BackendRefQueryDto {
pub(crate) names: Option<Vec<String>>,
pub(crate) namespace: Option<String>,
Expand Down
8 changes: 4 additions & 4 deletions admin/src/model/vo/http_route_vo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ pub struct SgHttpRouteVo {
/// Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process the request.
pub hostnames: Option<Vec<String>>,
/// [crate::model::vo::plugin_vo::SgFilterVo]'s id
pub filters: Option<Vec<String>>,
pub filters: Vec<String>,
/// Rules are a list of HTTP matchers, filters and actions.
pub rules: Option<Vec<SgHttpRouteRuleVo>>,
pub rules: Vec<SgHttpRouteRuleVo>,
}

impl Vo for SgHttpRouteVo {
Expand All @@ -40,9 +40,9 @@ pub struct SgHttpRouteRuleVo {
/// Matches define conditions used for matching the rule against incoming HTTP requests. Each match is independent, i.e. this rule will be matched if any one of the matches is satisfied.
pub matches: Option<Vec<SgHttpRouteMatch>>,
/// [crate::model::vo::plugin_vo::SgFilterVo]'s id
pub filters: Option<Vec<String>>,
pub filters: Vec<String>,
/// [crate::model::vo::backend_vo::SgBackendRefVo]'s id
pub backends: Option<Vec<String>>,
pub backends: Vec<String>,
/// Timeout define the timeout for requests that match this rule.
pub timeout_ms: Option<u64>,
}
35 changes: 5 additions & 30 deletions admin/src/model/vo_converter/gateway_vo_conv.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use crate::model::query_dto::{PluginQueryDto, ToInstance};
use crate::model::vo::gateway_vo::{SgGatewayVo, SgListenerVo, SgTlsConfigVo};
use crate::model::vo::plugin_vo::SgFilterVo;
use crate::model::vo_converter::plugin_vo_conv::SgFilterVoConv;
use crate::model::vo_converter::VoConv;
use crate::service::base_service::VoBaseService;
use crate::service::plugin_service::PluginVoService;
use crate::service::secret_service::TlsVoService;
use kernel_common::helper::k8s_helper::{format_k8s_obj_unique, parse_k8s_obj_unique};
use kernel_common::inner_model::gateway::{SgGateway, SgListener, SgTls, SgTlsConfig};
use tardis::async_trait::async_trait;
use tardis::basic::result::TardisResult;
Expand All @@ -14,45 +12,22 @@ use tardis::futures_util::future::join_all;
#[async_trait]
impl VoConv<SgGateway, SgGatewayVo> for SgGatewayVo {
async fn to_model(self) -> TardisResult<SgGateway> {
let filters = if !self.filters.is_empty() {
Some(
join_all(
PluginVoService::list(
PluginQueryDto {
ids: Some(self.filters),
..Default::default()
}
.to_instance()?,
)
.await?
.into_iter()
.map(|f| f.to_model())
.collect::<Vec<_>>(),
)
.await
.into_iter()
.collect::<TardisResult<Vec<_>>>()?,
)
} else {
None
};
Ok(SgGateway {
name: self.name,
parameters: self.parameters,
listeners: join_all(self.listeners.into_iter().map(|l| l.to_model()).collect::<Vec<_>>()).await.into_iter().collect::<TardisResult<Vec<_>>>()?,
filters,
filters: SgFilterVoConv::ids_to_filter(self.filters).await?,
})
}

async fn from_model(model: SgGateway) -> TardisResult<SgGatewayVo> {
let (namespace, _) = parse_k8s_obj_unique(&model.name);
let listeners = join_all(model.listeners.into_iter().map(|l| SgListenerVo::from_model(l)).collect::<Vec<_>>()).await.into_iter().collect::<TardisResult<Vec<_>>>()?;
let tls = listeners.iter().map(|l| l.tls_vo.clone()).filter(|t| t.is_some()).map(|t| t.unwrap()).collect::<Vec<_>>();
let listeners = join_all(model.listeners.into_iter().map(SgListenerVo::from_model).collect::<Vec<_>>()).await.into_iter().collect::<TardisResult<Vec<_>>>()?;
let tls = listeners.iter().filter_map(|l| l.tls_vo.clone()).collect::<Vec<_>>();
let filter_vo = if let Some(filters) = model.filters {
filters
.into_iter()
.map(|f| SgFilterVo {
id: format_k8s_obj_unique(Some(&namespace), &f.code),
id: format!("{}{}", &model.name, &f.code),
code: f.code,
name: f.name,
spec: f.spec,
Expand Down
85 changes: 82 additions & 3 deletions admin/src/model/vo_converter/http_route_conv.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,95 @@
use crate::model::vo::http_route_vo::SgHttpRouteVo;
use crate::model::query_dto::{BackendRefQueryDto, ToInstance};
use crate::model::vo::backend_vo::SgBackendRefVo;
use crate::model::vo::http_route_vo::{SgHttpRouteRuleVo, SgHttpRouteVo};
use crate::model::vo_converter::plugin_vo_conv::SgFilterVoConv;
use crate::model::vo_converter::VoConv;
use kernel_common::inner_model::http_route::SgHttpRoute;
use crate::service::backend_ref_service::BackendRefVoService;
use kernel_common::inner_model::http_route::{SgBackendRef, SgHttpRoute, SgHttpRouteRule};
use tardis::async_trait::async_trait;
use tardis::basic::result::TardisResult;
use tardis::futures_util::future::join_all;

#[async_trait]
impl VoConv<SgHttpRoute, SgHttpRouteVo> for SgHttpRouteVo {
async fn to_model(self) -> TardisResult<SgHttpRoute> {
Ok(SgHttpRoute {
name: self.name,
gateway_name: self.gateway_name,
hostnames: self.hostnames,
filters: SgFilterVoConv::ids_to_filter(self.filters).await?,
rules: if self.rules.is_empty() {
Some(join_all(self.rules.into_iter().map(|r| r.to_model()).collect::<Vec<_>>()).await.into_iter().collect::<TardisResult<Vec<_>>>()?)
} else {
None
},
})
}

async fn from_model(_model: SgHttpRoute) -> TardisResult<SgHttpRouteVo> {
todo!()
}
}

struct SgBackendRefVoConv;

impl SgBackendRefVoConv {
async fn ids_to_backends(ids: Vec<String>) -> TardisResult<Option<Vec<SgBackendRef>>> {
Ok(if ids.is_empty() {
Some(
join_all(
BackendRefVoService::list(
BackendRefQueryDto {
names: Some(ids),
..Default::default()
}
.to_instance()?,
)
.await?
.into_iter()
.map(|f| f.to_model())
.collect::<Vec<_>>(),
)
.await
.into_iter()
.collect::<TardisResult<Vec<_>>>()?,
)
} else {
None
})
}
}

#[async_trait]
impl VoConv<SgHttpRouteRule, SgHttpRouteRuleVo> for SgHttpRouteRuleVo {
async fn to_model(self) -> TardisResult<SgHttpRouteRule> {
Ok(SgHttpRouteRule {
matches: self.matches,
filters: SgFilterVoConv::ids_to_filter(self.filters).await?,
backends: SgBackendRefVoConv::ids_to_backends(self.backends).await?,
timeout_ms: self.timeout_ms,
})
}

async fn from_model(_model: SgHttpRouteRule) -> TardisResult<SgHttpRouteRuleVo> {
todo!()
}
}

#[async_trait]
impl VoConv<SgBackendRef, SgBackendRefVo> for SgBackendRefVo {
async fn to_model(self) -> TardisResult<SgBackendRef> {
Ok(SgBackendRef {
name_or_host: self.name_or_host,
namespace: self.namespace,
port: self.port,
timeout_ms: self.timeout_ms,
protocol: self.protocol,
weight: self.weight,
filters: SgFilterVoConv::ids_to_filter(self.filters.unwrap_or_default()).await?,
})
}

async fn from_model(model: SgHttpRoute) -> TardisResult<SgHttpRouteVo> {
async fn from_model(_model: SgBackendRef) -> TardisResult<SgBackendRefVo> {
todo!()
}
}
34 changes: 33 additions & 1 deletion admin/src/model/vo_converter/plugin_vo_conv.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
use crate::model::query_dto::{PluginQueryDto, ToInstance};
use crate::model::vo::plugin_vo::SgFilterVo;
use crate::model::vo_converter::VoConv;
use crate::service::plugin_service::PluginVoService;
use kernel_common::inner_model::plugin_filter::SgRouteFilter;
use tardis::async_trait::async_trait;
use tardis::basic::result::TardisResult;
use tardis::futures_util::future::join_all;

pub struct SgFilterVoConv {}

impl SgFilterVoConv {
pub(crate) async fn ids_to_filter(filters: Vec<String>) -> TardisResult<Option<Vec<SgRouteFilter>>> {
Ok(if filters.is_empty() {
Some(
join_all(
PluginVoService::list(
PluginQueryDto {
ids: Some(filters),
..Default::default()
}
.to_instance()?,
)
.await?
.into_iter()
.map(|f| f.to_model())
.collect::<Vec<_>>(),
)
.await
.into_iter()
.collect::<TardisResult<Vec<_>>>()?,
)
} else {
None
})
}
}

#[async_trait]
impl VoConv<SgRouteFilter, SgFilterVo> for SgFilterVo {
Expand All @@ -14,7 +46,7 @@ impl VoConv<SgRouteFilter, SgFilterVo> for SgFilterVo {
})
}

async fn from_model(model: SgRouteFilter) -> TardisResult<SgFilterVo> {
async fn from_model(_model: SgRouteFilter) -> TardisResult<SgFilterVo> {
todo!()
}
}
16 changes: 7 additions & 9 deletions admin/src/service/backend_ref_service.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::model::query_dto::{BackendRefQueryDto, BackendRefQueryInst};
use crate::model::query_dto::BackendRefQueryInst;
use crate::model::vo::backend_vo::SgBackendRefVo;
use crate::model::vo::Vo;

use crate::service::base_service::VoBaseService;
use kernel_common::helper::k8s_helper::{format_k8s_obj_unique, parse_k8s_unique_or_default};
use tardis::basic::error::TardisError;

use tardis::basic::result::TardisResult;

pub struct BackendRefVoService;
Expand All @@ -15,7 +14,6 @@ impl BackendRefVoService {
Ok(Self::get_type_map()
.await?
.into_values()
.into_iter()
.filter(|b|
if let Some(q_names) = &query.names {
q_names.iter().any(|q| q.is_match(&b.name_or_host))
Expand All @@ -24,7 +22,7 @@ impl BackendRefVoService {
} &&
if let Some(namespace) = &query.namespace {
if let Some(b_namespace)=&b.namespace{
namespace.is_match(&b_namespace)
namespace.is_match(b_namespace)
}
else { false }
} else {
Expand All @@ -35,14 +33,14 @@ impl BackendRefVoService {
}

pub(crate) async fn add(add: SgBackendRefVo) -> TardisResult<SgBackendRefVo> {
Ok(Self::add_vo(add).await?)
Self::add_vo(add).await
}
pub(crate) async fn update(update: SgBackendRefVo) -> TardisResult<SgBackendRefVo> {
Ok(Self::update_vo(update).await?)
Self::update_vo(update).await
}

pub(crate) async fn delete(id: &str) -> TardisResult<()> {
Self::delete_vo(&id).await?;
Self::delete_vo(id).await?;
Ok(())
}
}
17 changes: 9 additions & 8 deletions admin/src/service/base_service.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::constants::TYPE_CONFIG_NAME_MAP;
#[cfg(feature = "k8s")]
use crate::helper::get_k8s_client;
use crate::model::vo::Vo;
use k8s_openapi::api::core::v1::ConfigMap;
use k8s_openapi::apimachinery::pkg::apis::meta::v1::ObjectMeta;
use kube::api::PostParams;
use kube::Api;
#[cfg(feature = "k8s")]
use k8s_openapi::{api::core::v1::ConfigMap, apimachinery::pkg::apis::meta::v1::ObjectMeta};
#[cfg(feature = "k8s")]
use kube::{api::PostParams, Api};
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::collections::HashMap;
Expand Down Expand Up @@ -75,7 +76,7 @@ where
{
let id = config.get_unique_name();
let mut datas = Self::get_str_type_map().await?;
if let Some(_) = datas.get(&id) {
if datas.get(&id).is_some() {
if add_only {
return Err(TardisError::bad_request(&format!("[SG.admin] {}:{} already exists", T::get_vo_type(), id), ""));
} else {
Expand Down Expand Up @@ -110,7 +111,7 @@ where

async fn delete_vo(config_id: &str) -> TardisResult<()> {
let mut datas = Self::get_str_type_map().await?;
if let Some(_) = datas.remove(config_id) {
if datas.remove(config_id).is_some() {
get_config_map_api()
.await?
.replace(
Expand Down Expand Up @@ -313,13 +314,13 @@ mod test {
BackendRefVoService::add_vo(add_o_1.clone()).await.unwrap();
assert!(BackendRefVoService::add_vo(add_o_1.clone()).await.is_err());

let get_o_1 = serde_json::from_str::<SgBackendRefVo>(&BackendRefVoService::get_str_type_map().await.unwrap().get(&add_o_1.get_unique_name()).unwrap()).unwrap();
let get_o_1 = serde_json::from_str::<SgBackendRefVo>(BackendRefVoService::get_str_type_map().await.unwrap().get(&add_o_1.get_unique_name()).unwrap()).unwrap();
assert_eq!(get_o_1.port, add_o_1.port);

add_o_1.port = 1832;
BackendRefVoService::update_vo(add_o_1.clone()).await.unwrap();

let get_o_1 = serde_json::from_str::<SgBackendRefVo>(&BackendRefVoService::get_str_type_map().await.unwrap().get(&add_o_1.get_unique_name()).unwrap()).unwrap();
let get_o_1 = serde_json::from_str::<SgBackendRefVo>(BackendRefVoService::get_str_type_map().await.unwrap().get(&add_o_1.get_unique_name()).unwrap()).unwrap();
assert_eq!(get_o_1.port, add_o_1.port);

BackendRefVoService::delete_vo(&add_o_1.get_unique_name()).await.unwrap();
Expand Down
Loading

0 comments on commit defab1f

Please sign in to comment.