Skip to content

Notify subscribers when policy violation messages change - #7908

Open
007xf wants to merge 2 commits into
DependencyTrack:mainfrom
007xf:codex/issue-7649-violation-updates
Open

007xf wants to merge 2 commits into
DependencyTrack:mainfrom
007xf:codex/issue-7649-violation-updates

Conversation

@007xf

@007xf 007xf commented Nov 7, 2026 •

Copy link
Copy Markdown

Description

Add independently subscribed notifications when an existing component policy violation's
stored message changes. A message-producing KEV condition can report another matching
KEV while retaining the violation UUID. POLICY_VIOLATION keeps its creation-only meaning.

POLICY_VIOLATION_UPDATED reports ordinary updates. The separate
POLICY_VIOLATION_UPDATED_REVIEWED group explicitly opts into updates for approved or
suppressed violations. Existing rules gain neither subscription automatically, and review
decisions remain unchanged.

Addressed Issue

Addresses #7649.

Additional Details

Reconciliation requires an active READ COMMITTED transaction and locks the project in a
separate statement before the bulk upsert reads previous values. This avoids stale predecessor
values under PostgreSQL upsert conflicts. Null-safe comparison detects actual stored-message
transitions, including clearing a message; SQL captures previous/current values and statement
time. Violation changes and durable notification outbox entries commit or roll back together.
Existing project analysis workflows serialize full evaluations; direct callers must preserve that
contract because the reconciliation lock does not order earlier input reads.

One bulk subject query captures review metadata and classifies each transition once. Its
analysis join matches violation, component and project, ensuring only the corresponding review
tuple participates. APPROVED or suppressed=true selects the reviewed group; REJECTED/false
stays ordinary. Subscribing to both groups produces one event per transition. Reviewed subjects
include captured analysis state and suppression, preserving explicit false versus absent.
Ordinary subjects omit these optional review fields. Review-only changes,
new subscriptions and clearing a decision do not replay prior transitions or reset decisions.

Protobuf adds groups 25/26 and an update subject; optional review fields are appended as 7/8.
Existing enum numbers and fields remain unchanged. Text-based group storage needs no schema
migration. Router, CEL filters, Kafka partition keys and default publisher templates support both
groups. Consumers opting in must understand the new subject; custom templates may need an
explicit branch. Existing REST notification rules support independent subscription. Companion
changes are available in DependencyTrack/frontend#2074 and DependencyTrack/docs#324. The
frontend adds independent choices and accessible opt-in guidance; the documentation adds
configuration, filter and template guidance, and regenerated schema references. These remain unreleased.

Conditions must return a stable message containing relevant matching identities. Boolean
conditions and equal stored text cannot expose matching-set changes, including changes past
the existing 1024-character limit. Removal, replacement and wording changes also count; this
is not a semantic classifier of newly added KEVs. Delivery retains existing at-least-once retries
and permanent-failure diagnostics. Receivers should deduplicate by notification ID.

Validation used Temurin 25.0.5, real PostgreSQL 14.24 and process-local en_US/UTC settings:

  • Latest notification-router regression: 47 passed, zero failures/errors/skips, including
    presence-aware filters for absent values and an explicitly false suppression flag.
  • Clean default regression: 6,060 total; 5,972 passed; 88 skipped; zero failures/errors, in
    263.934 seconds. This includes 18 production-component CEL-to-webhook invocations,
    concurrent reconciliation, rollback, null transitions, subscription isolation, review ownership,
    templates and Protobuf compatibility. Skips comprise 80 inapplicable cases and eight existing
    disabled tests; they are not counted as passes.
  • Container HTTP scenarios: 3 passed, zero failures/errors/skips, covering approved-only,
    suppressed-only and combined decisions through authenticated REST configuration/review,
    the public analysis endpoint, persistent workflows and a local receiver. Synthetic KEV/finding
    fixtures use the isolated database. Cases verify default exclusion, opt-in, no duplicate events,
    no replay and future active updates.
  • Unified lint, Protobuf formatting/lint and the breaking check against the base passed.
  • Complete container E2E suite and its prerequisite official build passed: 12 total;
    10 passed; two skipped; zero failures/errors
    , in 226.546 seconds. The three new HTTP
    scenarios all ran. Existing Snyk organization and OSS Index username prerequisites were
    unavailable; those two tests were not executed or counted as passes.
  • The companion frontend passed 27 unit tests and all 278 real browser E2E cases, including
    eight new subscription cases, against the patched local API server and PostgreSQL. The latest
    backend commit only changes documentation and tests; production code matches the tested image.
  • Companion documentation passed strict build, full lint, 372 local link/anchor checks and six
    production-template-renderer scenarios. Its 392 existing prose warnings match the unchanged
    main baseline; added content has none. Frontend dependency audit and build diagnostics are
    documented in its PR rather than claimed resolved here.

Commands used for full regression, checks and final container validation:

export JAVA_TOOL_OPTIONS='-Duser.language=en -Duser.country=US -Duser.timezone=UTC'
make clean test AGENT=1 MVN_FLAGS='-B -q -Dsurefire.useFile=false -Dmaven.build.cache.enabled=false'
make lint AGENT=1
make format-proto lint-proto AGENT=1
buf breaking --against '.git#branch=main'
make test-e2e AGENT=1

Proposed ADR 044 and a repository usage note accompany the implementation. The ADR needs
Accepted status before merge. Companion changes need upstream merge/publication. Frontend CI
uses 5-snapshot and requires the backend implementation to merge and publish first. All commits
include the contributor's DCO sign-off.

Checklist

  • I have read and understand the contributing guidelines
  • This PR fixes a defect, and I have provided tests to verify that the fix is effective
  • This PR implements an enhancement, and I have provided tests to verify that it works as intended
  • This PR introduces changes to the database model, and I have updated the migration changelog accordingly (No schema change.)
  • This PR introduces new or alters existing behavior, and I have updated the documentation accordingly (Usage note and companion Document policy violation message update notifications docs#324; not yet merged or published.)
  • This PR is a substantial change (per the ADR criteria), and I have added an ADR under docs/adr/ (Proposed; acceptance before merge pending.)

Existing CEL violations retain their identity when matching content changes,
so later KEVs do not produce the creation notification. Persist message
transitions and notification outbox entries together, and expose separate
subscriptions for active and explicitly opted-in reviewed violations.

Preserve creation notifications and review decisions. Cover PostgreSQL
concurrency, rollback, review ownership and API-to-webhook delivery with
regression tests, and document the message-based contract in a proposed ADR.

Signed-off-by: WenFeng Gao <bd007xf@gmail.com>
@codacy-production

codacy-production Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 131 complexity

Metric Results
Complexity 131

View in Codacy

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.

Make the documented notification filters explicit about optional message and
review fields. Verify that absent values and a recorded false suppression
flag do not match the corresponding filters in the real notification router.

Signed-off-by: WenFeng Gao <bd007xf@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant