fix(tasks): emit change events on Task resolve/close/applySuggestion - #28140
fix(tasks): emit change events on Task resolve/close/applySuggestion#28140sonika-shah wants to merge 1 commit into
Conversation
`TaskResource.resolveTask`, `closeTask`, and `applySuggestion` returned
`Response.ok(...).build()` without `X-OpenMetadata-Change`, so the
`ChangeEventHandler` response filter produced no change event for task
lifecycle transitions. Subscriptions on `task + taskResolved` /
`taskClosed` could never fire; the audit log carried no row for
resolve/close turnarounds.
Setting `CHANGE_CUSTOM_HEADER` to `TASK_RESOLVED` / `TASK_CLOSED` on
these three responses restores parity with the legacy
`/v1/feed/tasks/{id}/resolve|close` routes (which emit the same event
types from `FeedRepository`) and unblocks the alert combinations that
were silently dropped after the Task System Redesign (#25894).
Related to #27889 — this is one of three remaining problems documented
in that issue; the bulk operations endpoint, orphan
`taskCreated` / `taskUpdated` `EventType` values, and the UI alert
builder offering unmatchable resource+eventType combinations need
separate follow-ups and a design decision.
There was a problem hiding this comment.
Pull request overview
Restores change-event emission for the new TaskResource endpoints /resolve, /close, and /applySuggestion by setting the X-OpenMetadata-Change response header so ChangeEventHandler produces taskResolved / taskClosed events. This re-enables EventSubscriptions and audit-log entries for the most semantically important Task transitions, regressed by the Task System Redesign (#25894).
Changes:
- Add
CHANGE_CUSTOM_HEADERwithTASK_RESOLVED/TASK_CLOSEDto the three endpoint responses. - Add two integration tests asserting the response header is set on resolve/close.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| openmetadata-service/.../tasks/TaskResource.java | Sets X-OpenMetadata-Change header on resolve/close/applySuggestion responses |
| openmetadata-integration-tests/.../TaskResourceIT.java | New tests verifying the header is emitted; adds a small direct-HTTP helper |
| ? HttpRequest.BodyPublishers.noBody() | ||
| : HttpRequest.BodyPublishers.ofString(body); | ||
| HttpRequest request = builder.method(method, publisher).build(); | ||
| return java.net.http.HttpClient.newHttpClient() |
There was a problem hiding this comment.
💡 Quality: Test uses fully-qualified class name instead of import
In the sendDirectJson helper at line 3795, java.net.http.HttpClient.newHttpClient() is used as a fully-qualified name instead of importing java.net.http.HttpClient at the top of the file. The custom review instructions require no fully-qualified names in code. Since HttpRequest and HttpResponse from the same package are already imported, HttpClient should be imported as well.
Import HttpClient and use unqualified name:
// Add to imports at top of file:
import java.net.http.HttpClient;
// Then replace line 3795:
return HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
Was this helpful? React with 👍 / 👎
Code Review 👍 Approved with suggestions 0 resolved / 1 findingsRestores task lifecycle event emission by adding missing change headers to resolve, close, and applySuggestion endpoints. Update the test helper to use an import instead of the fully-qualified class name. 💡 Quality: Test uses fully-qualified class name instead of import📄 openmetadata-integration-tests/src/test/java/org/openmetadata/it/tests/TaskResourceIT.java:3795 In the Import HttpClient and use unqualified name🤖 Prompt for agentsOptionsDisplay: compact → Showing less information. Comment with these commands to change:
Was this helpful? React with 👍 / 👎 | Gitar |
|
🟡 Playwright Results — all passed (15 flaky)✅ 4065 passed · ❌ 0 failed · 🟡 15 flaky · ⏭️ 92 skipped
🟡 15 flaky test(s) (passed on retry)
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |



Problem
TaskResource.resolveTask(POST /api/v1/tasks/{id}/resolve),closeTask(POST /api/v1/tasks/{id}/close), andapplySuggestion(POST /api/v1/tasks/{id}/applySuggestion) all returnedResponse.ok(resolvedTask).build()with noX-OpenMetadata-Changeheader. The JAX-RS response filterChangeEventHandleronly emits aChangeEventwhen that header is present (or when the status isCREATED), so:change_eventfor resolve/close turnarounds.EventSubscriptions onresource: task + filterByEventType: [taskResolved, taskClosed]could never fire — empty Recent Events, no email, no webhook.This regression was introduced by the Task System Redesign (#25894), which moved Task from a Thread sub-type to a first-class entity. The legacy
/v1/feed/tasks/{id}/resolve|closeroutes still emitTASK_RESOLVED/TASK_CLOSEDviaFeedRepository, but the newTaskResourceendpoints did not.Fix
Set
CHANGE_CUSTOM_HEADERon the three affected responses:POST /v1/tasks/{id}/resolvetaskResolvedPOST /v1/tasks/{id}/closetaskClosedPOST /v1/tasks/{id}/applySuggestiontaskResolvedFormatterUtil.createChangeEventForEntitythen builds aChangeEventwithentityType="task"andentity=<Task>, whichChangeEventHandlerpersists and forwards toEventSubscriptionconsumers — restoring parity with the legacy route and the eventType values already declared inchangeEventType.json.Tests
Two new integration tests in
TaskResourceIT:testResolveTaskEmitsTaskResolvedChangeEventHeader— assertsX-OpenMetadata-Change: taskResolvedon/resolve.testCloseTaskEmitsTaskClosedChangeEventHeader— assertsX-OpenMetadata-Change: taskClosedon/close.Both use a direct
java.net.http.HttpClientcall (the SDK'sHttpClientdoesn't expose response headers). Tests useTestNamespacefor isolation and run safely under@Execution(ExecutionMode.CONCURRENT).applySuggestionfollows the same one-line pattern; given the sameFormatterUtilmachinery handles all three identically, a focused header test on resolve+close is sufficient to prove the wiring. A future PR can extend coverage when Suggestion-task setup helpers are needed for unrelated reasons.Scope
Related to #27889 (do not auto-close — three other problems remain). This PR addresses only the missing change-event emission for
resolve/close/applySuggestionon the newTaskResource.Out of scope — needs separate work / design call
Bulk operations endpoint (
POST /v1/tasks/bulk) processes multiple tasks in one HTTP request. The single-valuedX-OpenMetadata-Changeheader can't express N events; fixing this needs per-task event emission from insideTaskWorkflowHandlerrather than via the response filter. Tracked separately.Orphan
taskCreated/taskUpdatedEventTypevalues are declared inchangeEventType.jsonbut emitted nowhere inopenmetadata-service. The newTaskResourceemitsentityCreated/entityUpdatedlike every other entity. Needs a design call: drop from the enum, or haveTaskResourceemitTASK_CREATED/TASK_UPDATEDinstead.UI alert builder (
AlertsUtil.tsx) still populatesfilterByEventTypefrom the entireEventTypeenum regardless of selected resource. Users can continue to save unreachable combinations. Depends on the outcome of (2) before the resource→eventTypes mapping can be defined.