Skip to content

Commit

Permalink
chore: work towards new API
Browse files Browse the repository at this point in the history
  • Loading branch information
ctron committed Jan 29, 2025
1 parent 498d54a commit 5a3bca8
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 37 deletions.
6 changes: 3 additions & 3 deletions modules/analysis/src/model/roots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ impl Roots for PaginatedResults<Node> {

impl Roots for Vec<Node> {
fn roots(self) -> Vec<Node> {
fn root_into(
fn roots_into(
nodes: impl IntoIterator<Item = Node>,
result: &mut HashMap<(String, String), Node>,
) {
for node in nodes.into_iter() {
root_into(node.ancestor.clone().into_iter().flatten(), result);
roots_into(node.ancestor.clone().into_iter().flatten(), result);

if let Some(true) = node.ancestor.as_ref().map(|a| a.is_empty()) {
result.insert((node.base.sbom_id.clone(), node.base.node_id.clone()), node);
Expand All @@ -34,7 +34,7 @@ impl Roots for Vec<Node> {
}

let mut result = HashMap::new();
root_into(self, &mut result);
roots_into(self, &mut result);

result.into_values().collect()
}
Expand Down
57 changes: 33 additions & 24 deletions modules/analysis/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use walk::*;
mod test;

use crate::{
model::{AnalysisStatus, BaseSummary, GraphMap, Node, PackageNode, Roots},
model::{AnalysisStatus, BaseSummary, GraphMap, Node, PackageNode},
Error,
};
use fixedbitset::FixedBitSet;
Expand Down Expand Up @@ -53,7 +53,7 @@ fn collect(
depth: u64,
discovered: &mut FixedBitSet,
) -> Option<Vec<Node>> {
log::debug!("Direction: {direction:?}");
tracing::debug!(direction = ?direction, "collecting for {node:?}");

if depth == 0 {
log::debug!("depth is zero");
Expand All @@ -70,18 +70,25 @@ fn collect(
let mut result = Vec::new();

for edge in graph.edges_directed(node, direction) {
let relationship = edge.weight();
let neighbor = edge.target();
log::debug!("edge {edge:?}");

let Some(package_node) = graph.node_weight(neighbor) else {
continue;
// we only recurse in one direction
let (ancestor, descendent, package_node) = match direction {
Direction::Incoming => (
collect(graph, edge.source(), direction, depth - 1, discovered),
None,
graph.node_weight(edge.source()),
),
Direction::Outgoing => (
None,
collect(graph, edge.target(), direction, depth - 1, discovered),
graph.node_weight(edge.target()),
),
};

let related = collect(graph, neighbor, direction, depth - 1, discovered);
// we only recurse in one direction
let (ancestor, descendent) = match direction {
Direction::Incoming => (related, None),
Direction::Outgoing => (None, related),
let relationship = edge.weight();
let Some(package_node) = package_node else {
continue;
};

result.push(Node {
Expand Down Expand Up @@ -210,11 +217,13 @@ impl AnalysisService {
F: FnMut(&Graph<PackageNode, Relationship>, NodeIndex, &PackageNode, &mut FixedBitSet),
{
let Some(graph) = graph.get(sbom_id) else {
// FIXME: we need a better strategy handling such errors
log::warn!("Unable to find SBOM: {sbom_id}");
return;
};

if is_cyclic_directed(graph) {
// FIXME: we need a better strategy handling such errors
log::warn!(
"analysis graph of sbom {} has circular references!",
sbom_id
Expand All @@ -230,7 +239,6 @@ impl AnalysisService {
.node_indices()
.filter(|&i| Self::filter(graph, &query, i))
.for_each(|node_index| {
log::debug!("matched!");
if visited.insert(node_index) {
if let Some(find_match_package_node) = graph.node_weight(node_index) {
f(graph, node_index, find_match_package_node, &mut discovered);
Expand Down Expand Up @@ -278,24 +286,25 @@ impl AnalysisService {
)
}

/// This function searches for a component(s) by name in a specific sbom, then returns that
/// component's root components.
pub async fn retrieve_all_sbom_roots_by_name<C: ConnectionTrait>(
/// locate components, retrieve dependency information, from a single SBOM
#[instrument(skip(self, connection), err)]
pub async fn retrieve_single<C: ConnectionTrait>(
&self,
sbom_id: Uuid,
component_name: String,
query: impl Into<GraphQuery<'_>> + Debug,
options: impl Into<QueryOptions> + Debug,
paginated: Paginated,
connection: &C,
) -> Result<Vec<Node>, Error> {
) -> Result<PaginatedResults<Node>, Error> {
let distinct_sbom_ids = vec![sbom_id.to_string()];
self.load_graphs(connection, &distinct_sbom_ids).await?;

let components = self.run_graph_query(
GraphQuery::Component(ComponentReference::Name(&component_name)),
QueryOptions::ancestors(),
distinct_sbom_ids,
);
let query = query.into();
let options = options.into();

Ok(components.roots())
self.load_graphs(connection, &distinct_sbom_ids).await?;
let components = self.run_graph_query(query, options, distinct_sbom_ids);

Ok(paginated.paginate_array(&components))
}

/// locate components, retrieve dependency information
Expand Down
2 changes: 1 addition & 1 deletion modules/analysis/src/service/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl AnalysisService {
) {
let _ = writeln!(
self.data,
r#""{source}" -> "{target}"maybe [label="{label}"]"#,
r#""{source}" -> "{target}" [label="{label}"]"#,
source = escape(&source.node_id),
target = escape(&target.node_id),
label = escape(&relationship.to_string())
Expand Down
38 changes: 29 additions & 9 deletions modules/analysis/src/service/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ async fn test_simple_analysis_service(ctx: &TrustifyContext) -> Result<(), anyho
Paginated::default(),
&ctx.db,
)
.await?
.roots();
.await?;

log::debug!("Before: {analysis_graph:#?}");
let analysis_graph = analysis_graph.roots();
log::debug!("After: {analysis_graph:#?}");

assert_eq!(
analysis_graph
Expand Down Expand Up @@ -65,8 +68,11 @@ async fn test_simple_analysis_service(ctx: &TrustifyContext) -> Result<(), anyho
Paginated::default(),
&ctx.db,
)
.await?
.roots();
.await?;

log::debug!("Before: {analysis_graph:#?}");
let analysis_graph = analysis_graph.roots();
log::debug!("After: {analysis_graph:#?}");

assert_eq!(analysis_graph.total, 1);

Expand Down Expand Up @@ -195,10 +201,11 @@ async fn test_simple_by_purl_analysis_service(ctx: &TrustifyContext) -> Result<(
Paginated::default(),
&ctx.db,
)
.await?
.roots();
.await?;

println!("{analysis_graph:#?}");
log::debug!("Before: {analysis_graph:#?}");
let analysis_graph = analysis_graph.roots();
log::debug!("After: {analysis_graph:#?}");

assert_ancestors(&analysis_graph.items, |ancestors| {
assert_eq!(
Expand Down Expand Up @@ -537,12 +544,25 @@ async fn test_retrieve_all_sbom_roots_by_name(ctx: &TrustifyContext) -> Result<(
.sbom_id
.parse::<Uuid>()?;

let dot = service.render_dot(&sbom_id.to_string()).unwrap();
println!("{dot}");

let roots = service
.retrieve_all_sbom_roots_by_name(sbom_id, component_name, &ctx.db)
.retrieve_single(
sbom_id,
ComponentReference::Name(&component_name),
QueryOptions::ancestors(),
Default::default(),
&ctx.db,
)
.await?;

log::debug!("Before: {roots:#?}");
let roots = roots.roots();
log::debug!("After: {roots:#?}");

assert_eq!(
roots.last().unwrap().name,
roots.items.last().unwrap().name,
"quarkus-bom-3.2.11.Final-redhat-00001"
);

Expand Down

0 comments on commit 5a3bca8

Please sign in to comment.