Add axum server to nym-api (#4803)

* Migrate nym-api HTTP server from rocket to axum (#4698)

Migrate endpoints to Axum

* Squashed after PR review

Initial WIP
- bootstrap axum server with same data as rocket
- start axum server alongside rocket
- add routes for circulating-supply, contract-cache, network
- write simple bash validation that migrated APIs return 200
- mark rocket parts of code as deprecated
- start more complicated routes: WIP

Init storage always

Add coconut routes

Add api-status routes

Expand tests

WIP

Migrate unstable APIs with query params

Update bash tests

Add node-status routes

Redirect / to /swagger

Update API tests

Implement graceful shutdown

rustfmt

Fix clippy

* Add ecash routes after rebase

* PR feedback
- add CORS layer
- move logger to common crate
- remove global log filters for nym-api and axum

* Serve OpenAPI for all endpoints (#4761)

* Playing around with swagger

* Generate OpenAPI for /status routes

* Phase out static_routes as strings
- also nest routers in a clearer way

* Generate OpenAPI for /network routes

* Generate OpenAPI for /api-status routes

* Generate OpenAPI for "nym nodes" routes

* Fix some network-monitor routes

* Generate OpenAPI for /ecash routes

* Add utoipa feature to /common mods

* Add OpenAPI for unstable routes

* Fix MixNodeDetails field in models

* Introduce axum feature flag (#4775)

* Add Axum bind_address to config

* Introduce axum feature flag

* Add comment to template.rs

* Add Github action to build wtih `axum` feature

* Refactor server start & shutdown (#4777)

* Clippy: don't forget axum feature

* Refactor router so it's safer

* Implement graceful shutdown

* Nicer pattern matching

* Better Result syntax
This commit is contained in:
Dinko Zdravac
2024-08-29 15:31:01 +02:00
committed by GitHub
parent afc1b90b57
commit a0fea6edb4
68 changed files with 4653 additions and 428 deletions
+2 -1
View File
@@ -41,12 +41,13 @@ pub struct NodeStatusCache {
impl NodeStatusCache {
/// Creates a new cache with no data.
fn new() -> NodeStatusCache {
pub(crate) fn new() -> NodeStatusCache {
NodeStatusCache {
inner: Arc::new(RwLock::new(NodeStatusCacheData::new())),
}
}
#[deprecated(note = "TODO rocket: obsolete because it's used for Rocket")]
pub fn stage() -> AdHoc {
AdHoc::on_ignite("Node Status Cache", |rocket| async {
rocket.manage(Self::new())
+16 -26
View File
@@ -52,12 +52,11 @@ pub(super) fn split_into_active_and_rewarded_set(
}
pub(super) async fn get_mixnode_performance_from_storage(
storage: &Option<NymApiStorage>,
storage: &NymApiStorage,
mix_id: MixId,
epoch: Interval,
) -> Option<Performance> {
storage
.as_ref()?
.get_average_mixnode_uptime_in_the_last_24hrs(
mix_id,
epoch.current_epoch_end_unix_timestamp(),
@@ -68,12 +67,11 @@ pub(super) async fn get_mixnode_performance_from_storage(
}
pub(super) async fn get_gateway_performance_from_storage(
storage: &Option<NymApiStorage>,
storage: &NymApiStorage,
gateway_id: &str,
epoch: Interval,
) -> Option<Performance> {
storage
.as_ref()?
.get_average_gateway_uptime_in_the_last_24hrs(
gateway_id,
epoch.current_epoch_end_unix_timestamp(),
@@ -84,7 +82,7 @@ pub(super) async fn get_gateway_performance_from_storage(
}
pub(super) async fn annotate_nodes_with_details(
storage: &Option<NymApiStorage>,
storage: &NymApiStorage,
mixnodes: Vec<MixNodeDetails>,
interval_reward_params: RewardingParams,
current_interval: Interval,
@@ -123,16 +121,12 @@ pub(super) async fn annotate_nodes_with_details(
current_interval,
);
let node_performance = if let Some(storage) = storage {
storage
.construct_mixnode_report(mixnode.mix_id())
.await
.map(NodePerformance::from)
.ok()
} else {
None
}
.unwrap_or_default();
let node_performance = storage
.construct_mixnode_report(mixnode.mix_id())
.await
.map(NodePerformance::from)
.ok()
.unwrap_or_default();
// safety: this conversion is infallible
let ip_addresses =
@@ -177,7 +171,7 @@ pub(super) async fn annotate_nodes_with_details(
}
pub(crate) async fn annotate_gateways_with_details(
storage: &Option<NymApiStorage>,
storage: &NymApiStorage,
gateway_bonds: Vec<GatewayBond>,
current_interval: Interval,
blacklist: &HashSet<IdentityKey>,
@@ -192,16 +186,12 @@ pub(crate) async fn annotate_gateways_with_details(
.await
.unwrap_or_default();
let node_performance = if let Some(storage) = storage {
storage
.construct_gateway_report(gateway_bond.identity())
.await
.map(NodePerformance::from)
.ok()
} else {
None
}
.unwrap_or_default();
let node_performance = storage
.construct_gateway_report(gateway_bond.identity())
.await
.map(NodePerformance::from)
.ok()
.unwrap_or_default();
// safety: this conversion is infallible
let ip_addresses = match NetworkAddress::from_str(&gateway_bond.gateway.host).unwrap() {
+2 -2
View File
@@ -29,7 +29,7 @@ pub struct NodeStatusCacheRefresher {
// Sources for when refreshing data
contract_cache: NymContractCache,
contract_cache_listener: watch::Receiver<CacheNotification>,
storage: Option<NymApiStorage>,
storage: NymApiStorage,
}
impl NodeStatusCacheRefresher {
@@ -38,7 +38,7 @@ impl NodeStatusCacheRefresher {
fallback_caching_interval: Duration,
contract_cache: NymContractCache,
contract_cache_listener: watch::Receiver<CacheNotification>,
storage: Option<NymApiStorage>,
storage: NymApiStorage,
) -> Self {
Self {
cache,