2026-03-31 19:19:04 +08:00
|
|
|
use axum::extract::State;
|
|
|
|
|
use axum::response::IntoResponse;
|
|
|
|
|
use axum::routing::get;
|
|
|
|
|
use axum::Json;
|
|
|
|
|
use axum::Router;
|
|
|
|
|
use serde_json::json;
|
|
|
|
|
|
2026-04-05 20:23:16 +08:00
|
|
|
use crate::constants::{
|
2026-04-04 01:40:24 +08:00
|
|
|
FRONTDOOR_MANIFEST_PATH, FRONTDOOR_MANIFEST_VERSION, INTERNAL_FRONTDOOR_MANIFEST_PATH,
|
|
|
|
|
INTERNAL_GATEWAY_PATH_PREFIXES, INTERNAL_GATEWAY_ROUTE_GROUPS, READYZ_PATH,
|
|
|
|
|
RUST_FRONTDOOR_OWNED_ROUTE_PATTERNS,
|
2026-03-31 19:19:04 +08:00
|
|
|
};
|
2026-04-05 20:23:16 +08:00
|
|
|
use crate::AppState;
|
2026-03-31 19:19:04 +08:00
|
|
|
|
|
|
|
|
pub(crate) fn mount_core_routes(router: Router<AppState>) -> Router<AppState> {
|
|
|
|
|
router
|
|
|
|
|
.route(FRONTDOOR_MANIFEST_PATH, get(frontdoor_manifest))
|
|
|
|
|
.route(INTERNAL_FRONTDOOR_MANIFEST_PATH, get(frontdoor_manifest))
|
|
|
|
|
.route(READYZ_PATH, get(readyz))
|
|
|
|
|
.route("/_gateway/health", get(health))
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-23 00:26:07 +08:00
|
|
|
fn current_gateway_version() -> &'static str {
|
|
|
|
|
option_env!("AETHER_BUILD_VERSION")
|
|
|
|
|
.filter(|version| !version.is_empty())
|
|
|
|
|
.unwrap_or(env!("CARGO_PKG_VERSION"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 19:19:04 +08:00
|
|
|
pub(crate) async fn health(State(state): State<AppState>) -> impl IntoResponse {
|
|
|
|
|
let request_concurrency = state.request_concurrency_snapshot().map(|snapshot| {
|
|
|
|
|
json!({
|
|
|
|
|
"limit": snapshot.limit,
|
|
|
|
|
"in_flight": snapshot.in_flight,
|
|
|
|
|
"available_permits": snapshot.available_permits,
|
|
|
|
|
"high_watermark": snapshot.high_watermark,
|
|
|
|
|
"rejected": snapshot.rejected,
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
let distributed_request_concurrency = state
|
|
|
|
|
.distributed_request_concurrency_snapshot()
|
|
|
|
|
.await
|
|
|
|
|
.ok()
|
|
|
|
|
.flatten()
|
|
|
|
|
.map(|snapshot| {
|
|
|
|
|
json!({
|
|
|
|
|
"limit": snapshot.limit,
|
|
|
|
|
"in_flight": snapshot.in_flight,
|
|
|
|
|
"available_permits": snapshot.available_permits,
|
|
|
|
|
"high_watermark": snapshot.high_watermark,
|
|
|
|
|
"rejected": snapshot.rejected,
|
|
|
|
|
})
|
|
|
|
|
});
|
2026-07-31 10:59:15 +08:00
|
|
|
let websocket_connection_concurrency =
|
|
|
|
|
state
|
|
|
|
|
.websocket_connection_concurrency_snapshot()
|
|
|
|
|
.map(|snapshot| {
|
|
|
|
|
json!({
|
|
|
|
|
"limit": snapshot.limit,
|
|
|
|
|
"in_flight": snapshot.in_flight,
|
|
|
|
|
"available_permits": snapshot.available_permits,
|
|
|
|
|
"high_watermark": snapshot.high_watermark,
|
|
|
|
|
"rejected": snapshot.rejected,
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
let distributed_websocket_connection_concurrency = state
|
|
|
|
|
.distributed_websocket_connection_concurrency_snapshot()
|
|
|
|
|
.await
|
|
|
|
|
.ok()
|
|
|
|
|
.flatten()
|
|
|
|
|
.map(|snapshot| {
|
|
|
|
|
json!({
|
|
|
|
|
"limit": snapshot.limit,
|
|
|
|
|
"in_flight": snapshot.in_flight,
|
|
|
|
|
"available_permits": snapshot.available_permits,
|
|
|
|
|
"high_watermark": snapshot.high_watermark,
|
|
|
|
|
"rejected": snapshot.rejected,
|
|
|
|
|
})
|
|
|
|
|
});
|
2026-03-31 19:19:04 +08:00
|
|
|
Json(json!({
|
|
|
|
|
"status": "ok",
|
|
|
|
|
"component": "aether-gateway",
|
2026-04-03 14:59:58 +08:00
|
|
|
"control_api_enabled": true,
|
2026-03-31 19:19:04 +08:00
|
|
|
"request_concurrency": request_concurrency,
|
|
|
|
|
"distributed_request_concurrency": distributed_request_concurrency,
|
2026-07-31 10:59:15 +08:00
|
|
|
"websocket_connection_concurrency": websocket_connection_concurrency,
|
|
|
|
|
"distributed_websocket_connection_concurrency": distributed_websocket_connection_concurrency,
|
2026-03-31 19:19:04 +08:00
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) async fn readyz(State(_state): State<AppState>) -> impl IntoResponse {
|
|
|
|
|
Json(json!({
|
|
|
|
|
"status": "ready",
|
|
|
|
|
"component": "aether-gateway",
|
|
|
|
|
"manifest_version": FRONTDOOR_MANIFEST_VERSION,
|
|
|
|
|
"manifest_path": FRONTDOOR_MANIFEST_PATH,
|
|
|
|
|
"warmup_status": "disabled",
|
|
|
|
|
"gate_readiness": false,
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) async fn frontdoor_manifest(State(state): State<AppState>) -> impl IntoResponse {
|
|
|
|
|
let frontdoor_cors = state.frontdoor_cors();
|
|
|
|
|
let cors_enabled = frontdoor_cors.is_some();
|
|
|
|
|
let cors_allow_credentials = frontdoor_cors
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|config| config.allow_credentials())
|
|
|
|
|
.unwrap_or(false);
|
|
|
|
|
let cors_allowed_origins = frontdoor_cors
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|config| config.allowed_origins().to_vec())
|
|
|
|
|
.unwrap_or_default();
|
|
|
|
|
Json(json!({
|
|
|
|
|
"component": "aether-gateway",
|
|
|
|
|
"manifest_version": FRONTDOOR_MANIFEST_VERSION,
|
2026-05-23 00:26:07 +08:00
|
|
|
"version": current_gateway_version(),
|
2026-03-31 19:19:04 +08:00
|
|
|
"mode": "compatibility_frontdoor",
|
|
|
|
|
"entrypoints": {
|
|
|
|
|
"public_manifest": FRONTDOOR_MANIFEST_PATH,
|
|
|
|
|
"operational_manifest": INTERNAL_FRONTDOOR_MANIFEST_PATH,
|
|
|
|
|
"readiness": READYZ_PATH,
|
|
|
|
|
"health": "/_gateway/health",
|
|
|
|
|
"metrics": "/_gateway/metrics",
|
|
|
|
|
},
|
|
|
|
|
"rust_frontdoor": {
|
|
|
|
|
"owned_route_patterns": RUST_FRONTDOOR_OWNED_ROUTE_PATTERNS,
|
|
|
|
|
"capabilities": {
|
|
|
|
|
"public_proxy_catch_all": true,
|
|
|
|
|
"admin_proxy_passthrough": true,
|
|
|
|
|
"internal_proxy_passthrough": true,
|
|
|
|
|
"trace_id_injection": true,
|
|
|
|
|
"compatibility_proxy": true,
|
|
|
|
|
},
|
2026-04-04 01:40:24 +08:00
|
|
|
"internal_gateway": {
|
|
|
|
|
"route_groups": INTERNAL_GATEWAY_ROUTE_GROUPS,
|
|
|
|
|
"path_prefixes": INTERNAL_GATEWAY_PATH_PREFIXES,
|
2026-09-04 03:45:52 +08:00
|
|
|
"status": state.internal_gateway_auth_status(),
|
2026-03-31 19:19:04 +08:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"features": {
|
2026-04-03 14:59:58 +08:00
|
|
|
"control_api_configured": true,
|
|
|
|
|
"execution_runtime_configured": state.execution_runtime_configured(),
|
2026-03-31 19:19:04 +08:00
|
|
|
"request_concurrency_enabled": state.request_concurrency_snapshot().is_some(),
|
|
|
|
|
"distributed_request_concurrency_enabled": state.distributed_request_gate.is_some(),
|
2026-07-31 10:59:15 +08:00
|
|
|
"websocket_connection_concurrency_enabled": state
|
|
|
|
|
.websocket_connection_concurrency_snapshot()
|
|
|
|
|
.is_some(),
|
|
|
|
|
"distributed_websocket_connection_concurrency_enabled": state
|
|
|
|
|
.distributed_websocket_connection_gate
|
|
|
|
|
.is_some(),
|
2026-03-31 19:19:04 +08:00
|
|
|
"frontdoor_cors_enabled": cors_enabled,
|
|
|
|
|
"frontdoor_cors_allow_credentials": cors_allow_credentials,
|
|
|
|
|
"frontdoor_cors_allowed_origins": cors_allowed_origins,
|
|
|
|
|
},
|
|
|
|
|
}))
|
|
|
|
|
}
|