feat: new matcher system instead of manually 'match'ing in servcie
This commit is contained in:
parent
f305cb5a85
commit
638b0376d8
15 changed files with 646 additions and 225 deletions
157
src/routes/api.rs
Normal file
157
src/routes/api.rs
Normal file
|
@ -0,0 +1,157 @@
|
|||
use async_trait::async_trait;
|
||||
use base64::{Engine, prelude::BASE64_STANDARD};
|
||||
use http::request::Parts;
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::{Method, StatusCode};
|
||||
use log::{debug, error, warn};
|
||||
|
||||
use crate::{
|
||||
config::Client,
|
||||
db::Endpoint,
|
||||
matchers::api::ApiMatcher,
|
||||
server::{custom_resp, json_to_vec},
|
||||
services::matcher::Route,
|
||||
};
|
||||
|
||||
pub struct AddHost {}
|
||||
|
||||
#[async_trait]
|
||||
impl Route<ApiMatcher> for AddHost {
|
||||
fn matcher(&self, _: &ApiMatcher, req: &hyper::Request<hyper::body::Incoming>) -> bool {
|
||||
req.uri().path().starts_with("/endpoint/") && req.method() == Method::POST
|
||||
}
|
||||
|
||||
async fn call(
|
||||
&self,
|
||||
m: &ApiMatcher,
|
||||
parts: Parts,
|
||||
) -> Result<crate::server::GeneralResponse, hyper::Error> {
|
||||
let database = m.database.clone();
|
||||
let address = m._address.unwrap();
|
||||
let body = m.body.clone().unwrap();
|
||||
|
||||
let endpoint_id: u32 = parts.uri.path().replace("/endpoint/", "").parse().unwrap();
|
||||
|
||||
if !body["hosts"].is_array() {
|
||||
error!("Hosts parameter is not an array.",);
|
||||
|
||||
return Ok(custom_resp(
|
||||
StatusCode::BAD_REQUEST,
|
||||
"Hosts parameter is not an array.".to_string(),
|
||||
)
|
||||
.await);
|
||||
}
|
||||
|
||||
let endpoint = match Endpoint::get_by_id(*database.lock().await, endpoint_id)
|
||||
.await
|
||||
.unwrap()
|
||||
{
|
||||
Some(x) => x,
|
||||
None => {
|
||||
error!("No endpoint found by id {endpoint_id} from {address}",);
|
||||
|
||||
return Ok(custom_resp(
|
||||
StatusCode::NOT_FOUND,
|
||||
"No endpoint by that ID.".to_string(),
|
||||
)
|
||||
.await);
|
||||
}
|
||||
};
|
||||
|
||||
let hosts = json_to_vec(body["hosts"].clone()).await.unwrap();
|
||||
|
||||
endpoint.host(*database.lock().await, hosts).await.unwrap();
|
||||
|
||||
Ok(custom_resp(StatusCode::OK, "Success".to_string()).await)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RegisterEndpoint {}
|
||||
|
||||
#[async_trait]
|
||||
impl Route<ApiMatcher> for RegisterEndpoint {
|
||||
fn matcher(&self, _: &ApiMatcher, req: &hyper::Request<hyper::body::Incoming>) -> bool {
|
||||
req.uri().path() == "/register" && req.method() == Method::POST
|
||||
}
|
||||
|
||||
async fn call(
|
||||
&self,
|
||||
m: &ApiMatcher,
|
||||
_: Parts,
|
||||
) -> Result<crate::server::GeneralResponse, hyper::Error> {
|
||||
let address = m._address.unwrap();
|
||||
let database = m.database.clone();
|
||||
let body = m.body.clone().unwrap();
|
||||
|
||||
let mut endpoint = Endpoint::new(
|
||||
None,
|
||||
address,
|
||||
body["port"].as_u16().unwrap_or(8080),
|
||||
body["callback"].as_str().unwrap_or("/").to_string(),
|
||||
)
|
||||
.await;
|
||||
|
||||
if !body["hosts"].is_array() {
|
||||
error!("Hosts parameter is not an array.",);
|
||||
|
||||
return Ok(custom_resp(
|
||||
StatusCode::BAD_REQUEST,
|
||||
"Hosts parameter is not an array.".to_string(),
|
||||
)
|
||||
.await);
|
||||
};
|
||||
|
||||
let hosts = json_to_vec(body["hosts"].clone()).await.unwrap();
|
||||
|
||||
endpoint
|
||||
.register(*database.lock().await, hosts)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let endpoint_id = endpoint.id.unwrap().to_string();
|
||||
|
||||
let response = custom_resp(StatusCode::OK, endpoint_id).await;
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RemoveHost {}
|
||||
|
||||
#[async_trait]
|
||||
impl Route<ApiMatcher> for RemoveHost {
|
||||
fn matcher(&self, _: &ApiMatcher, req: &hyper::Request<hyper::body::Incoming>) -> bool {
|
||||
req.uri().path().starts_with("/endpoint/") && req.method() == Method::DELETE
|
||||
}
|
||||
|
||||
async fn call(
|
||||
&self,
|
||||
m: &ApiMatcher,
|
||||
parts: Parts,
|
||||
) -> Result<crate::server::GeneralResponse, hyper::Error> {
|
||||
let database = m.database.clone();
|
||||
let address = m._address.unwrap();
|
||||
|
||||
let endpoint_id: u32 = parts.uri.path().replace("/endpoint/", "").parse().unwrap();
|
||||
|
||||
let endpoint = match Endpoint::get_by_id(*database.lock().await, endpoint_id)
|
||||
.await
|
||||
.unwrap()
|
||||
{
|
||||
Some(x) => x,
|
||||
None => {
|
||||
error!("No endpoint found by id {endpoint_id} from {address}",);
|
||||
|
||||
return Ok(custom_resp(
|
||||
StatusCode::NOT_FOUND,
|
||||
"No endpoint by that ID.".to_string(),
|
||||
)
|
||||
.await);
|
||||
}
|
||||
};
|
||||
|
||||
endpoint.delete(*database.lock().await).await.unwrap();
|
||||
|
||||
Ok(custom_resp(StatusCode::OK, "Success".to_string()).await)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue