-
Notifications
You must be signed in to change notification settings - Fork 7
/
sample.rs
178 lines (155 loc) · 5.43 KB
/
sample.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
use axum::{
async_trait,
extract::{FromRequestParts, Path},
http::{request::Parts, StatusCode},
response::{IntoResponse, Response},
routing::get,
RequestPartsExt, Router,
};
use crate::common::uranium::uranium_server::{Uranium, UraniumServer};
use crate::common::uranium::{HealthCheckRequest, HealthCheckResponse};
use tonic::{transport::Server, Request, Response as GrpcResponse, Status};
// use migration::{sea_orm::DatabaseConnection, Migrator, MigratorTrait};
use sea_orm::{ConnectOptions, Database};
use std::{collections::HashMap, env, net::SocketAddr, time::Duration};
use tower_http::{
cors::{Any, CorsLayer},
trace::TraceLayer,
};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use crate::config::app_state::AppState;
mod common;
mod config;
mod extractors;
mod handlers;
mod router;
mod utils;
/// the grpc server
#[derive(Debug, Default)]
pub struct UraniumCore;
#[tonic::async_trait]
impl Uranium for UraniumCore {
#[doc = " Returns the current health of the Uranium service."]
#[must_use]
#[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
/* async fn health_check(
self,
request: tonic::Request<HealthCheckRequest>,
) -> Result<tonic::Response<HealthCheckResponse>, Status> {
let status = HealthCheckResponse {
status: "Service Healthy\n".to_string(),
};
/*
mismatched types
expected struct `Pin<Box<(dyn Future<Output = Result<tonic::Response<HealthCheckResponse>, Status>> + Send + 'async_trait)>>`
found enum `Result<(tonic::Response<HealthCheckResponse>, Status), _>`rustcClick for full compiler diagnostic
lib.rs(45, 10): expected `Pin<Box<(dyn Future<Output = Result<tonic::Response<HealthCheckResponse>, Status>> + Send + 'async_trait)>>` because of return type
*
Ok((
GrpcResponse::new(status),
Status::new(tonic::Code::Ok, "all goog"),
))
} */
}
// pub struct Uranium;
// impl Uranium {
/// Create a new instance of the application. This will load configuration and setup logging as well
pub async fn run() {
dotenvy::dotenv().ok();
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
// axum logs rejections from built-in extractors with the `axum::rejection`
// target, at `TRACE` level. `axum::rejection=trace` enables showing those events
"example_tracing_aka_logging=debug,tower_http=debug,axum::rejection=trace".into()
}),
)
.with(tracing_subscriber::fmt::layer())
.init();
let database_connection_string =
env::var("DATABASE_URL").expect("database URL is not provided in env variable");
let mut opt = ConnectOptions::new(database_connection_string);
opt.max_connections(100)
.min_connections(5)
.connect_timeout(Duration::from_secs(8))
.acquire_timeout(Duration::from_secs(8))
.idle_timeout(Duration::from_secs(8))
.max_lifetime(Duration::from_secs(8))
.sqlx_logging(true)
.sqlx_logging_level(log::LevelFilter::Info)
.set_schema_search_path("uranium".to_owned());
let connection = Database::connect(opt)
.await
.expect("error connecting to database ");
//initialize cors layer
let cors = CorsLayer::new()
.allow_origin(Any)
.allow_methods(Any)
.allow_headers(Any);
let trace = TraceLayer::new_for_http();
let state = AppState {
database: connection,
};
// build our application with some routes
let app = Router::new()
.route("/", get(health_check))
.nest("/:version/", router::routes(&state))
.layer(trace)
.layer(cors)
.fallback(handle_404);
// run the migration
// Migrator::up(&connection, None).await.unwrap();
let addr = SocketAddr::from(([0, 0, 0, 0], 53467));
println!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
// }
/// #health check
/// the health check is typically bounded to the server base URL to check the status of the app
/// this can b eeasliy done with cURl
/// for example
/// ```sh
/// curl 0.0.0.0:53467
/// ```
async fn health_check() -> &'static str {
"Service is healthy\n"
}
/// 404 handler
async fn handle_404() -> impl IntoResponse {
(
StatusCode::NOT_FOUND,
axum::response::Json(serde_json::json!({
"success":false,
"message":String::from("The requested resource does not exist on this server!"),
})),
)
}
#[derive(Debug)]
enum Version {
V1,
V2,
V3,
}
#[async_trait]
impl<S> FromRequestParts<S> for Version
where
S: Send + Sync,
{
type Rejection = Response;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
let params: Path<HashMap<String, String>> =
parts.extract().await.map_err(IntoResponse::into_response)?;
let version = params
.get("version")
.ok_or_else(|| (StatusCode::NOT_FOUND, "version param missing").into_response())?;
match version.as_str() {
"v1" => Ok(Version::V1),
"v2" => Ok(Version::V2),
"v3" => Ok(Version::V3),
_ => Err((StatusCode::NOT_FOUND, "unknown version").into_response()),
}
}
}