use crate::nns::inventory::{
NnsInventoryInputKind, NnsInventoryResolveError, resolve_nns_inventory_row,
};
use super::{
NNS_NODE_INFO_REPORT_SCHEMA_VERSION, NnsInventoryInfoRequest, NnsNodeHostError,
NnsNodeInfoReport, NnsNodeListReport, NnsNodeListRequest,
cache::{load_cached_nns_node_report, nns_node_cache_path},
filters::filter_node_list_report,
refresh::refresh_nns_node_report_with_source,
source::NnsNodeSource,
};
use crate::nns::{LiveNnsSource, inventory::load_or_refresh_nns_inventory_report};
use crate::{QueryProgress, progress::IgnoreQueryProgress};
pub async fn build_nns_node_list_report(
request: &NnsNodeListRequest,
) -> Result<NnsNodeListReport, NnsNodeHostError> {
build_nns_node_list_report_with_source(request, &LiveNnsSource::default()).await
}
pub async fn build_nns_node_info_report(
request: &NnsInventoryInfoRequest,
) -> Result<NnsNodeInfoReport, NnsNodeHostError> {
build_nns_node_info_report_with_source(request, &LiveNnsSource::default()).await
}
pub async fn build_nns_node_list_report_with_progress(
request: &NnsNodeListRequest,
progress: &mut dyn QueryProgress,
) -> Result<NnsNodeListReport, NnsNodeHostError> {
build_nns_node_list_report_with_source_and_progress(
request,
&LiveNnsSource::default(),
progress,
)
.await
}
pub async fn build_nns_node_list_report_with_source(
request: &NnsNodeListRequest,
source: &dyn NnsNodeSource,
) -> Result<NnsNodeListReport, NnsNodeHostError> {
build_nns_node_list_report_with_source_and_progress(request, source, &mut IgnoreQueryProgress)
.await
}
pub async fn build_nns_node_list_report_with_source_and_progress(
request: &NnsNodeListRequest,
source: &dyn NnsNodeSource,
progress: &mut dyn QueryProgress,
) -> Result<NnsNodeListReport, NnsNodeHostError> {
let report = load_or_refresh_nns_inventory_report(
&request.inventory,
nns_node_cache_path(
&request.inventory.cache.cache_root,
&request.inventory.cache.network,
),
progress,
|cache| load_cached_nns_node_report(cache).map(|cached| cached.report),
async |refresh_request| {
refresh_nns_node_report_with_source(refresh_request, source)
.await
.map(|_| ())
},
)
.await?;
Ok(filter_node_list_report(report, &request.filters))
}
pub async fn build_nns_node_info_report_with_progress(
request: &NnsInventoryInfoRequest,
progress: &mut dyn QueryProgress,
) -> Result<NnsNodeInfoReport, NnsNodeHostError> {
build_nns_node_info_report_with_source_and_progress(
request,
&LiveNnsSource::default(),
progress,
)
.await
}
pub async fn build_nns_node_info_report_with_source(
request: &NnsInventoryInfoRequest,
source: &dyn NnsNodeSource,
) -> Result<NnsNodeInfoReport, NnsNodeHostError> {
build_nns_node_info_report_with_source_and_progress(request, source, &mut IgnoreQueryProgress)
.await
}
pub async fn build_nns_node_info_report_with_source_and_progress(
request: &NnsInventoryInfoRequest,
source: &dyn NnsNodeSource,
progress: &mut dyn QueryProgress,
) -> Result<NnsNodeInfoReport, NnsNodeHostError> {
let list_request = NnsNodeListRequest::new(
request.cache.clone(),
request.source_endpoint.clone(),
request.now_unix_secs,
);
let mut report =
build_nns_node_list_report_with_source_and_progress(&list_request, source, progress)
.await?;
let (index, resolved_from) = resolve_node(&report, &request.input)?;
let node = report.nodes.swap_remove(index);
Ok(NnsNodeInfoReport {
schema_version: NNS_NODE_INFO_REPORT_SCHEMA_VERSION,
input: request.input.clone(),
resolved_from,
provenance: report.provenance,
node,
})
}
pub(super) fn resolve_node(
report: &NnsNodeListReport,
input: &str,
) -> Result<(usize, String), NnsNodeHostError> {
resolve_nns_inventory_row(
&report.nodes,
|row| row.node_principal.as_str(),
input,
NnsInventoryInputKind::Principal,
"node_principal",
)
.map_err(|error| match error {
NnsInventoryResolveError::NotFound { input } => NnsNodeHostError::NodeNotFound { input },
NnsInventoryResolveError::Ambiguous { prefix, matches } => {
NnsNodeHostError::AmbiguousNodePrefix { prefix, matches }
}
})
}