api: fetch addresses from config.

This commit is contained in:
Sachin Kamath
2024-12-17 15:05:24 +05:30
committed by Mark Sinclair
parent 94ab78606a
commit 4f07343efd
3 changed files with 47 additions and 92 deletions
+3 -1
View File
@@ -8,6 +8,7 @@ use utoipa_swagger_ui::SwaggerUi;
use crate::http::{api_docs, server::HttpServer, state::AppState};
pub(crate) mod price;
pub(crate) mod watcher;
pub(crate) struct RouterBuilder {
unfinished_router: Router<AppState>,
@@ -24,7 +25,8 @@ impl RouterBuilder {
"/",
axum::routing::get(|| async { Redirect::permanent("/swagger") }),
)
.nest("/v1", Router::new().nest("/price", price::routes()));
.nest("/v1", Router::new().nest("/price", price::routes()))
.nest("/v1", Router::new().nest("/watcher", watcher::routes()));
Self {
unfinished_router: router,
-91
View File
@@ -1,91 +0,0 @@
use axum::Router;
use core::net::SocketAddr;
use tokio::{net::TcpListener, task::JoinHandle};
use tokio_util::sync::{CancellationToken, WaitForCancellationFutureOwned};
use crate::{
db::DbPool,
http::{api::RouterBuilder, state::AppState},
};
/// Return handles that allow for graceful shutdown of server + awaiting its
/// background tokio task
pub(crate) async fn start_http_api(
db_pool: DbPool,
http_port: u16,
nym_http_cache_ttl: u64,
) -> anyhow::Result<ShutdownHandles> {
let router_builder = RouterBuilder::with_default_routes();
let state = AppState::new(db_pool, nym_http_cache_ttl);
let router = router_builder.with_state(state);
let bind_addr = format!("0.0.0.0:{}", http_port);
let server = router.build_server(bind_addr).await?;
Ok(start_server(server))
}
fn start_server(server: HttpServer) -> ShutdownHandles {
// one copy is stored to trigger a graceful shutdown later
let shutdown_button = CancellationToken::new();
// other copy is given to server to listen for a shutdown
let shutdown_receiver = shutdown_button.clone();
let shutdown_receiver = shutdown_receiver.cancelled_owned();
let server_handle = tokio::spawn(async move { server.run(shutdown_receiver).await });
ShutdownHandles {
server_handle,
shutdown_button,
}
}
pub(crate) struct ShutdownHandles {
server_handle: JoinHandle<std::io::Result<()>>,
shutdown_button: CancellationToken,
}
impl ShutdownHandles {
/// Send graceful shutdown signal to server and wait for server task to complete
pub(crate) async fn shutdown(self) -> anyhow::Result<()> {
self.shutdown_button.cancel();
match self.server_handle.await {
Ok(Ok(_)) => {
tracing::info!("HTTP server shut down without errors");
}
Ok(Err(err)) => {
tracing::error!("HTTP server terminated with: {err}");
anyhow::bail!(err)
}
Err(err) => {
tracing::error!("Server task panicked: {err}");
}
};
Ok(())
}
}
pub(crate) struct HttpServer {
router: Router,
listener: TcpListener,
}
impl HttpServer {
pub(crate) fn new(router: Router, listener: TcpListener) -> Self {
Self { router, listener }
}
pub(crate) async fn run(self, receiver: WaitForCancellationFutureOwned) -> std::io::Result<()> {
// into_make_service_with_connect_info allows us to see client ip address
axum::serve(
self.listener,
self.router
.into_make_service_with_connect_info::<SocketAddr>(),
)
.with_graceful_shutdown(receiver)
.await
}
}
+44
View File
@@ -0,0 +1,44 @@
use crate::config::Config;
use crate::http::error::Error;
use crate::http::error::HttpResult;
use crate::http::state::AppState;
use axum::{Json, Router};
pub(crate) fn routes() -> Router<AppState> {
Router::new().route("/addresses", axum::routing::get(get_addresses))
}
#[utoipa::path(
tag = "Watcher Configuration",
get,
path = "/v1/watcher/addresses",
responses(
(status = 200, body = Vec<String>)
)
)]
/// Fetch the addresses being watched by the chain watcher
async fn get_addresses() -> HttpResult<Json<Vec<String>>> {
let config =
Config::read_from_toml_file_in_default_location().map_err(|_| Error::internal())?;
let addresses = config
.payment_watcher_config
.as_ref()
.and_then(|config| {
config.watchers.iter().find_map(|watcher| {
watcher
.watch_for_transfer_recipient_accounts
.as_ref()
.map(|accounts| {
accounts
.iter()
.map(|account| account.to_string())
.collect::<Vec<_>>()
})
})
})
.unwrap_or_default();
Ok(Json(addresses))
}