Conversation
…e-bulk-data-access # Conflicts: # src/Microsoft.Health.Fhir.SqlServer/Features/Schema/Migrations/103.diff.sql # src/Microsoft.Health.Fhir.SqlServer/Features/Schema/Migrations/103.sql
There was a problem hiding this comment.
Pull request overview
This PR updates Bulk Export cancellation behavior across SQL and Cosmos queue implementations, including schema changes and expanded test coverage, to better handle “cancel requested” semantics for export orchestrator jobs that have already completed or failed.
Changes:
- Adds logic to mark Export orchestrator jobs as
CancelRequestedeven when alreadyCompleted/Failed(SQL sproc + Cosmos queue client). - Updates export job status retrieval/cancellation flows to treat canceled/cancel-requested jobs as “not found” in more cases.
- Introduces SQL schema version 104 and adds/updates integration + unit tests covering these scenarios.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| test/Microsoft.Health.Fhir.Shared.Tests.Integration/Persistence/QueueClientTests.cs | Adds integration tests validating CancelRequested behavior for completed/failed export orchestrator jobs. |
| test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/FhirOperationDataStoreExportTests.cs | Adds extensive integration test coverage for export job retrieval and cancellation-related outcomes. |
| src/Microsoft.Health.Fhir.SqlServer/Microsoft.Health.Fhir.SqlServer.csproj | Bumps SQL LatestSchemaVersion to 104. |
| src/Microsoft.Health.Fhir.SqlServer/Features/Schema/Sql/Sprocs/PutJobCancelation.sql | Updates cancellation sproc logic to set CancelRequested for completed/failed export orchestrator jobs. |
| src/Microsoft.Health.Fhir.SqlServer/Features/Schema/SchemaVersionConstants.cs | Updates max schema version constant to V104. |
| src/Microsoft.Health.Fhir.SqlServer/Features/Schema/SchemaVersion.cs | Adds schema enum value V104. |
| src/Microsoft.Health.Fhir.SqlServer/Features/Schema/Migrations/104.diff.sql | Adds migration for updated PutJobCancelation sproc (but needs adjustment). |
| src/Microsoft.Health.Fhir.CosmosDb/Features/Storage/Queues/CosmosQueueClient.cs | Mirrors export orchestrator CancelRequested behavior for completed/failed jobs in Cosmos. |
| src/Microsoft.Health.Fhir.Core/Features/Operations/JobRecordProperties.cs | Adds CancelRequested job-record property name constant. |
| src/Microsoft.Health.Fhir.Core/Features/Operations/FhirOperationDataStoreBase.cs | Adjusts export job retrieval to incorporate group cancellation semantics and propagate group id into outcomes. |
| src/Microsoft.Health.Fhir.Core/Features/Operations/Export/Models/ExportJobRecord.cs | Adds CancelRequested field and loosens setter for GroupId for internal population. |
| src/Microsoft.Health.Fhir.Core/Features/Operations/Export/CancelExportRequestHandler.cs | Updates cancel handler behavior for canceled/completed/failed export jobs. |
| src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/Export/CancelExportRequestHandlerTests.cs | Updates and expands unit tests for updated cancel/export behavior. |
src/Microsoft.Health.Fhir.Core/Features/Operations/Export/CancelExportRequestHandler.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Health.Fhir.SqlServer/Features/Schema/Migrations/104.diff.sql
Outdated
Show resolved
Hide resolved
src/Microsoft.Health.Fhir.Core/Features/Operations/FhirOperationDataStoreBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Health.Fhir.Core/Features/Operations/FhirOperationDataStoreBase.cs
Outdated
Show resolved
Hide resolved
...ealth.Fhir.Shared.Tests.Integration/Features/Operations/FhirOperationDataStoreExportTests.cs
Outdated
Show resolved
Hide resolved
...ealth.Fhir.Shared.Tests.Integration/Features/Operations/FhirOperationDataStoreExportTests.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Health.Fhir.Core/Features/Operations/FhirOperationDataStoreBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Health.Fhir.CosmosDb/Features/Storage/Queues/CosmosQueueClient.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Health.Fhir.Core/Features/Operations/FhirOperationDataStoreBase.cs
Fixed
Show fixed
Hide fixed
src/Microsoft.Health.Fhir.CosmosDb/Features/Storage/Queues/CosmosQueueClient.cs
Fixed
Show fixed
Hide fixed
...ealth.Fhir.Shared.Tests.Integration/Features/Operations/FhirOperationDataStoreExportTests.cs
Fixed
Show fixed
Hide fixed
...ealth.Fhir.Shared.Tests.Integration/Features/Operations/FhirOperationDataStoreExportTests.cs
Fixed
Show fixed
Hide fixed
| if (record.FailureDetails == null) | ||
| { | ||
| record.FailureDetails = new JobFailureDetails(Core.Resources.ProcessingJobHadNoResults, HttpStatusCode.InternalServerError); | ||
| } | ||
| else | ||
| { | ||
| record.FailureDetails = new JobFailureDetails(record.FailureDetails.FailureReason + "\r\n" + Core.Resources.ProcessingJobHadNoResults, record.FailureDetails.FailureStatusCode); | ||
| } |
Check notice
Code scanning / CodeQL
Missed ternary opportunity Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 days ago
In general, to fix a “missed ternary opportunity” where both branches of an if assign the same variable, we replace the if/else with a single assignment that uses the conditional (?:) operator to select between the two values.
Here, both branches assign record.FailureDetails:
- If
record.FailureDetails == null, assignnew JobFailureDetails(Core.Resources.ProcessingJobHadNoResults, HttpStatusCode.InternalServerError). - Else, assign
new JobFailureDetails(record.FailureDetails.FailureReason + "\r\n" + Core.Resources.ProcessingJobHadNoResults, record.FailureDetails.FailureStatusCode).
We can replace the whole if/else with:
record.FailureDetails = record.FailureDetails == null
? new JobFailureDetails(Core.Resources.ProcessingJobHadNoResults, HttpStatusCode.InternalServerError)
: new JobFailureDetails(record.FailureDetails.FailureReason + "\r\n" + Core.Resources.ProcessingJobHadNoResults, record.FailureDetails.FailureStatusCode);This preserves all behavior: the same condition is checked and the same constructor arguments are used; we only change syntax. No new imports, methods, or definitions are required. The change is confined to the else branch inside the foreach loop in FhirOperationDataStoreBase.cs around original lines 132–139.
| @@ -129,14 +129,14 @@ | ||
| } | ||
| else | ||
| { | ||
| if (record.FailureDetails == null) | ||
| { | ||
| record.FailureDetails = new JobFailureDetails(Core.Resources.ProcessingJobHadNoResults, HttpStatusCode.InternalServerError); | ||
| } | ||
| else | ||
| { | ||
| record.FailureDetails = new JobFailureDetails(record.FailureDetails.FailureReason + "\r\n" + Core.Resources.ProcessingJobHadNoResults, record.FailureDetails.FailureStatusCode); | ||
| } | ||
| record.FailureDetails = record.FailureDetails == null | ||
| ? new JobFailureDetails(Core.Resources.ProcessingJobHadNoResults, HttpStatusCode.InternalServerError) | ||
| : new JobFailureDetails(record.FailureDetails.FailureReason + "\r\n" + Core.Resources.ProcessingJobHadNoResults, record.FailureDetails.FailureStatusCode); | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| } | ||
| } | ||
|
|
Description
This PR improves Bulk Export (Bulk Data Access 2.0) cancellation behavior by introducing a CancelRequested flag on the orchestrator/group export job. This enables consistent cancel semantics even when the orchestrator job has already Completed or Failed, and aligns job retrieval behavior when cancellation is requested.
Key changes
Core
CancelRequestedtoExportJobRecordandJobRecordProperties.CancelExportRequestHandlerto:CancelRequestedand return 404 if already requested; otherwise return 202 Accepted without changing job status to Canceled.FhirOperationDataStoreBaseto treatJobStatus.Cancelledand group/orchestratorCancelRequestedas JobNotFound when reading export jobs, and to propagateId/GroupIdconsistently.UpdateExportJobAsyncto cancel by group id and throw JobNotFound when the job does not exist.Cosmos DB
CosmosQueueClient.CancelJobByGroupIdAsyncto setCancelRequested = truefor the export orchestrator job even if it is already Completed/Failed.SQL Server
PutJobCancelationsproc to setCancelRequested = 1for the export orchestrator job (JobId == GroupId) when status is Completed/Failed.Tests
CancelExportRequestHandlercovering:CancelRequestedImpact / Notes
Related issues
Addresses 179823.
Testing
Describe how this change was tested.
FHIR Team Checklist
Semver Change (docs)
Patch|Skip|Feature|Breaking (reason)