Add direct dependency flag to component for efficient direct/transitive dependency filtering#6206
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
6496a06 to
ab7ca1f
Compare
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
| Duplication | 1 |
🟢 Coverage 100.00% diff coverage · -0.08% coverage variation
Metric Results Coverage variation ✅ -0.08% coverage variation (-1.00%) Diff coverage ✅ 100.00% diff coverage (70.00%) Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (073d435) 41636 35833 86.06% Head commit (0310c52) 41646 (+10) 35807 (-26) 85.98% (-0.08%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#6206) 10 10 100.00% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Signed-off-by: Sahiba Mittal <sahiba.mittal@citi.com>
Signed-off-by: Sahiba Mittal <sahiba.mittal@citi.com>
8e1e25f to
0310c52
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds a denormalized direct dependency flag to components so direct/transitive dependency filtering can use a boolean column instead of JSONB containment checks.
Changes:
- Adds
COMPONENT.DIRECTpersistence, migration, model accessors, and BOM-import population logic. - Updates project component listing, v1 filtering, CEL policy mapping/proto support, and response schemas.
- Adjusts tests and JSON assertions for the new direct flag.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
proto/src/main/proto/org/dependencytrack/policy/v1/policy.proto |
Adds is_direct to policy component proto. |
migration/src/main/resources/org/dependencytrack/migration/V202605291156__add_direct_column_to_component.sql |
Adds the DIRECT column and index. |
apiserver/src/main/java/org/dependencytrack/model/Component.java |
Adds persisted direct field and accessors. |
apiserver/src/main/java/org/dependencytrack/tasks/ImportBomActivity.java |
Recomputes direct flags after dependency graph import. |
apiserver/src/main/java/org/dependencytrack/persistence/jdbi/ComponentDao.java |
Uses and maintains DIRECT in project component queries. |
apiserver/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java |
Switches legacy direct filtering to DIRECT. |
apiserver/src/main/java/org/dependencytrack/resources/v2/ProjectsResource.java |
Includes direct in v2 project component responses. |
api/src/main/openapi/resources/projects/schemas/list-project-components-response-item.yaml |
Documents direct in the v2 response schema. |
apiserver/src/main/java/org/dependencytrack/policy/cel/persistence/CelPolicyFieldMappingRegistry.java |
Exposes is_direct to CEL field selection. |
apiserver/src/main/java/org/dependencytrack/policy/cel/persistence/CelPolicyDao.java |
Reads direct dependency status from COMPONENT.DIRECT. |
apiserver/src/main/java/org/dependencytrack/policy/cel/persistence/CelPolicyComponentRowMapper.java |
Maps is_direct into CEL policy component protos. |
apiserver/src/main/java/org/dependencytrack/model/mapping/PolicyProtoMapper.java |
Maps model component direct status into policy proto. |
apiserver/src/test/java/org/dependencytrack/resources/v2/ProjectsResourceTest.java |
Updates v2 project component response expectations. |
apiserver/src/test/java/org/dependencytrack/resources/v2/ComponentsResourceTest.java |
Updates component creation response expectations. |
apiserver/src/test/java/org/dependencytrack/resources/v1/VulnerabilityResourceTest.java |
Updates nested component JSON expectations. |
apiserver/src/test/java/org/dependencytrack/resources/v1/ComponentResourceTest.java |
Updates component JSON expectations and setup. |
apiserver/src/test/java/org/dependencytrack/policy/cel/persistence/CelPolicyDaoTest.java |
Updates CEL field-loading JSON expectations. |
apiserver/src/test/java/org/dependencytrack/policy/cel/compat/VersionDistanceCelPolicyEvaluatorTest.java |
Updates direct-dependency setup for version-distance policies. |
apiserver/src/test/java/org/dependencytrack/policy/cel/CelPolicyEngineTest.java |
Updates CEL policy direct-dependency setup. |
apiserver/src/test/java/org/dependencytrack/persistence/jdbi/ComponentDaoTest.java |
Adds coverage for recomputing DIRECT. |
apiserver/src/test/java/org/dependencytrack/persistence/ComponentQueryManangerPostgresTest.java |
Updates legacy component-query tests to use DIRECT. |
| whereConditions.add(/* language=SQL */ """ | ||
| EXISTS ( | ||
| SELECT 1 | ||
| FROM "PROJECT" | ||
| WHERE "PROJECT"."ID" = "C"."PROJECT_ID" | ||
| AND "PROJECT"."DIRECT_DEPENDENCIES" @> JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('uuid', "C"."UUID")) | ||
| )"""); | ||
| AND "C"."DIRECT" IS TRUE | ||
| """); |
| queryString += | ||
| """ | ||
| AND "B0"."DIRECT_DEPENDENCIES" @> JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('uuid', "A0"."UUID")) | ||
| AND "A0"."DIRECT" = TRUE |
| ALTER TABLE "COMPONENT" | ||
| ADD COLUMN "DIRECT" BOOLEAN; |
| SELECT COALESCE(c."DIRECT", FALSE) | ||
| FROM "COMPONENT" c | ||
| WHERE c."UUID" = CAST(:uuid AS UUID) |
| try (final Handle jdbiHandle = createLocalJdbi(qm).open()) { | ||
| jdbiHandle.attach(ComponentDao.class).setDirect(project.getId()); | ||
| } |
There was a problem hiding this comment.
Whether a component is a direct dependency could be determined here as well:
| @Persistent | ||
| @Column(name = "DIRECT", allowsNull = "true") | ||
| @JsonProperty("isDirect") | ||
| private Boolean direct; |
There was a problem hiding this comment.
Can we disambiguate the name? e.g. call it directDependency / isDirectDependency.
There was a problem hiding this comment.
Let's also add the new field to the "all fields" test:
There was a problem hiding this comment.
Might want to think about backfilling the new column. Otherwise existing deployments will be in an awkward state where the new column is NULL, but the "is direct dependency" information is technically known based on the project's DIRECT_DEPENDENCIES column.
That would lead to the new column being unreliable until new BOMs are uploaded to all projects.
There was a problem hiding this comment.
Yes plan was to make it nullable to avoid heavy migration for existing components (number can be in millions for deployed components) and can be populated upon next bom upload/publish.
Description
Add
directdependency flag to component for efficient direct/transitive dependency filtering.Addressed Issue
Ports PR from Hyades Apiserver
#6183
DependencyTrack/hyades-apiserver#2168
Additional Details
Checklist
docs/adr/