safety(web-gateway): use configured CORS origins, add health/readiness probes
- Replace CorsLayer::allow_origin(Any) with configured cors_origins whitelist
- Add GET /health liveness probe (returns {"status":"ok"})
- Add GET /ready readiness probe (reports gRPC channel availability)
- Fix unused import warning in auth middleware tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,7 +41,6 @@ mod tests {
|
||||
use axum::body::Body;
|
||||
use axum::http::{Request as HttpRequest, StatusCode};
|
||||
use axum::middleware;
|
||||
use axum::response::IntoResponse;
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use jsonwebtoken::{encode, EncodingKey, Header};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use tower_http::cors::{Any, CorsLayer};
|
||||
use axum::http::HeaderValue;
|
||||
use tower_http::cors::CorsLayer;
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::info;
|
||||
|
||||
@@ -19,16 +20,23 @@ async fn main() -> Result<()> {
|
||||
info!(" Trading service: {}", config.trading_service_url);
|
||||
info!(" Backtesting service: {}", config.backtesting_service_url);
|
||||
info!(" ML Training service: {}", config.ml_training_service_url);
|
||||
info!(" CORS origins: {:?}", config.cors_origins);
|
||||
|
||||
let state = AppState::new(config).await?;
|
||||
let state = AppState::new(config.clone()).await?;
|
||||
|
||||
// Start gRPC stream bridge tasks (forward gRPC streams to WebSocket broadcast)
|
||||
start_grpc_stream_bridges(state.trading_channel.clone(), state.ws_broadcast.clone());
|
||||
|
||||
// Build CORS from configured origins
|
||||
let origins: Vec<HeaderValue> = config
|
||||
.cors_origins
|
||||
.iter()
|
||||
.filter_map(|o| o.parse().ok())
|
||||
.collect();
|
||||
let cors = CorsLayer::new()
|
||||
.allow_origin(Any)
|
||||
.allow_methods(Any)
|
||||
.allow_headers(Any);
|
||||
.allow_origin(origins)
|
||||
.allow_methods(tower_http::cors::Any)
|
||||
.allow_headers(tower_http::cors::Any);
|
||||
|
||||
let app = create_router(state)
|
||||
.layer(cors)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use axum::{middleware, routing, Router};
|
||||
use axum::{middleware, routing, Json, Router};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::auth::middleware::auth_middleware;
|
||||
use crate::state::AppState;
|
||||
@@ -36,9 +37,30 @@ pub fn create_router(state: AppState) -> Router {
|
||||
// WebSocket endpoint validates JWT via query param (no middleware layer)
|
||||
let ws_route = Router::new().route("/ws", routing::get(ws_handler));
|
||||
|
||||
// Health/readiness probes (public, no auth)
|
||||
let health = Router::new()
|
||||
.route("/health", routing::get(health_check))
|
||||
.route("/ready", routing::get(readiness_check));
|
||||
|
||||
Router::new()
|
||||
.nest("/api", rest_api)
|
||||
.nest("/api", public_api)
|
||||
.nest("/api", ws_route)
|
||||
.merge(health)
|
||||
.with_state(state)
|
||||
}
|
||||
|
||||
async fn health_check() -> Json<serde_json::Value> {
|
||||
Json(json!({ "status": "ok" }))
|
||||
}
|
||||
|
||||
async fn readiness_check(
|
||||
axum::extract::State(state): axum::extract::State<AppState>,
|
||||
) -> Json<serde_json::Value> {
|
||||
Json(json!({
|
||||
"status": "ok",
|
||||
"trading_service": state.trading_channel.is_some(),
|
||||
"backtesting_service": state.backtesting_channel.is_some(),
|
||||
"ml_training_service": state.ml_training_channel.is_some(),
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user