Skip to content

Commit

Permalink
Merge pull request #795 from DependencyTrack/port-log-warning-for-mis…
Browse files Browse the repository at this point in the history
…sing-dep-graph-root-node

Port : log warning when dependency graph is missing the root node
  • Loading branch information
nscuro authored Jul 23, 2024
2 parents 6a93f7a + 2ac0dbb commit 13e8f4d
Showing 1 changed file with 65 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,12 @@ private ProcessedBom processBom(final Context ctx, final ConsumedBom bom) {
}
}

private static Project processProject(final Context ctx, final QueryManager qm,
final Project project, final ProjectMetadata projectMetadata) {
private static Project processProject(
final Context ctx,
final QueryManager qm,
final Project project,
final ProjectMetadata projectMetadata
) {
final Query<Project> query = qm.getPersistenceManager().newQuery(Project.class);
query.setFilter("uuid == :uuid");
query.setParameters(ctx.project.getUuid());
Expand Down Expand Up @@ -426,11 +430,13 @@ private static Project processProject(final Context ctx, final QueryManager qm,
return persistentProject;
}

private static Map<ComponentIdentity, Component> processComponents(final QueryManager qm,
final Project project,
final List<Component> components,
final Map<String, ComponentIdentity> identitiesByBomRef,
final MultiValuedMap<ComponentIdentity, String> bomRefsByIdentity) {
private static Map<ComponentIdentity, Component> processComponents(
final QueryManager qm,
final Project project,
final List<Component> components,
final Map<String, ComponentIdentity> identitiesByBomRef,
final MultiValuedMap<ComponentIdentity, String> bomRefsByIdentity
) {
assertPersistent(project, "Project must be persistent");

// Fetch IDs of all components that exist in the project already.
Expand Down Expand Up @@ -529,11 +535,13 @@ private static Map<ComponentIdentity, Component> processComponents(final QueryMa
return persistentComponents;
}

private static Map<ComponentIdentity, ServiceComponent> processServices(final QueryManager qm,
final Project project,
final List<ServiceComponent> services,
final Map<String, ComponentIdentity> identitiesByBomRef,
final MultiValuedMap<ComponentIdentity, String> bomRefsByIdentity) {
private static Map<ComponentIdentity, ServiceComponent> processServices(
final QueryManager qm,
final Project project,
final List<ServiceComponent> services,
final Map<String, ComponentIdentity> identitiesByBomRef,
final MultiValuedMap<ComponentIdentity, String> bomRefsByIdentity
) {
assertPersistent(project, "Project must be persistent");

// Fetch IDs of all services that exist in the project already.
Expand Down Expand Up @@ -584,15 +592,23 @@ private static Map<ComponentIdentity, ServiceComponent> processServices(final Qu
return persistentServices;
}

private void processDependencyGraph(final QueryManager qm,
final Project project,
final MultiValuedMap<String, String> dependencyGraph,
final Map<ComponentIdentity, Component> componentsByIdentity,
final Map<String, ComponentIdentity> identitiesByBomRef) {
private void processDependencyGraph(
final QueryManager qm,
final Project project,
final MultiValuedMap<String, String> dependencyGraph,
final Map<ComponentIdentity, Component> componentsByIdentity,
final Map<String, ComponentIdentity> identitiesByBomRef
) {
assertPersistent(project, "Project must be persistent");

if (project.getBomRef() != null) {
final Collection<String> directDependencyBomRefs = dependencyGraph.get(project.getBomRef());
if (directDependencyBomRefs == null || directDependencyBomRefs.isEmpty()) {
LOGGER.warn("""
The dependency graph has %d entries, but the project (metadata.component node of the BOM) \
is not one of them; Graph will be incomplete because it is not possible to determine its root\
""".formatted(dependencyGraph.size()));
}
final String directDependenciesJson = resolveDirectDependenciesJson(project.getBomRef(), directDependencyBomRefs, identitiesByBomRef);
if (!Objects.equals(directDependenciesJson, project.getDirectDependencies())) {
project.setDirectDependencies(directDependenciesJson);
Expand Down Expand Up @@ -650,9 +666,11 @@ private static void recordBomImport(final Context ctx, final QueryManager qm, fi
project.setLastBomImportFormat("%s %s".formatted(ctx.bomFormat.getFormatShortName(), ctx.bomSpecVersion));
}

private String resolveDirectDependenciesJson(final String dependencyBomRef,
final Collection<String> directDependencyBomRefs,
final Map<String, ComponentIdentity> identitiesByBomRef) {
private String resolveDirectDependenciesJson(
final String dependencyBomRef,
final Collection<String> directDependencyBomRefs,
final Map<String, ComponentIdentity> identitiesByBomRef
) {
if (directDependencyBomRefs == null || directDependencyBomRefs.isEmpty()) {
return null;
}
Expand Down Expand Up @@ -701,10 +719,12 @@ private static long deleteServicesById(final QueryManager qm, final Collection<L
return pm.newQuery(ServiceComponent.class, ":ids.contains(id)").deletePersistentAll(serviceIds);
}

private static void resolveAndApplyLicense(final QueryManager qm,
final Component component,
final Map<String, License> licenseCache,
final Map<String, License> customLicenseCache) {
private static void resolveAndApplyLicense(
final QueryManager qm,
final Component component,
final Map<String, License> licenseCache,
final Map<String, License> customLicenseCache
) {
// CycloneDX components can declare multiple licenses, but we currently
// only support one. We assume that the licenseCandidates list is ordered
// by priority, and simply take the first resolvable candidate.
Expand Down Expand Up @@ -788,8 +808,10 @@ private static <T> Set<Long> getAllComponentIds(final QueryManager qm, final Pro
}
}

private static Predicate<Component> distinctComponentsByIdentity(final Map<String, ComponentIdentity> identitiesByBomRef,
final MultiValuedMap<ComponentIdentity, String> bomRefsByIdentity) {
private static Predicate<Component> distinctComponentsByIdentity(
final Map<String, ComponentIdentity> identitiesByBomRef,
final MultiValuedMap<ComponentIdentity, String> bomRefsByIdentity
) {
final var identitiesSeen = new HashSet<ComponentIdentity>();
return component -> {
final var componentIdentity = new ComponentIdentity(component);
Expand All @@ -814,8 +836,10 @@ private static Predicate<Component> distinctComponentsByIdentity(final Map<Strin
};
}

private static Predicate<ServiceComponent> distinctServicesByIdentity(final Map<String, ComponentIdentity> identitiesByBomRef,
final MultiValuedMap<ComponentIdentity, String> bomRefsByIdentity) {
private static Predicate<ServiceComponent> distinctServicesByIdentity(
final Map<String, ComponentIdentity> identitiesByBomRef,
final MultiValuedMap<ComponentIdentity, String> bomRefsByIdentity
) {
final var identitiesSeen = new HashSet<ComponentIdentity>();
return service -> {
final var componentIdentity = new ComponentIdentity(service);
Expand Down Expand Up @@ -870,7 +894,11 @@ private static void completeBomProcessingWorkflowStep(final Context ctx) {
}
}

private static void failWorkflowStepAndCancelDescendants(final Context ctx, final WorkflowStep step, final Throwable failureCause) {
private static void failWorkflowStepAndCancelDescendants(
final Context ctx,
final WorkflowStep step,
final Throwable failureCause
) {
try (var qm = new QueryManager()) {
qm.runInTransaction(() -> {
final var now = new Date();
Expand All @@ -883,7 +911,10 @@ private static void failWorkflowStepAndCancelDescendants(final Context ctx, fina
}
}

private List<CompletableFuture<?>> initiateVulnerabilityAnalysis(final Context ctx, final Collection<ComponentVulnerabilityAnalysisEvent> events) {
private List<CompletableFuture<?>> initiateVulnerabilityAnalysis(
final Context ctx,
final Collection<ComponentVulnerabilityAnalysisEvent> events
) {
if (events.isEmpty()) {
// No components to be sent for vulnerability analysis.
// If the BOM_PROCESSED notification was delayed, dispatch it now.
Expand Down Expand Up @@ -989,7 +1020,10 @@ private void dispatchBomProcessingFailedNotification(final Context ctx, final Th
.subject(new BomProcessingFailed(ctx.token, ctx.project, /* bom */ "(Omitted)", throwable.getMessage(), ctx.bomFormat, ctx.bomSpecVersion)));
}

private static List<ComponentVulnerabilityAnalysisEvent> createVulnAnalysisEvents(final Context ctx, final Collection<Component> components) {
private static List<ComponentVulnerabilityAnalysisEvent> createVulnAnalysisEvents(
final Context ctx,
final Collection<Component> components
) {
return components.stream()
.map(component -> new ComponentVulnerabilityAnalysisEvent(
ctx.token,
Expand Down

0 comments on commit 13e8f4d

Please sign in to comment.