Skip to content

Fix $bulk-delete bugs with custom search parameter #4964

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 48 commits into
base: main
Choose a base branch
from

Conversation

tarunmathew12
Copy link
Contributor

Description

The PR will address an issue of the search parameter status going out of sync after $bulk-delete removes search parameter resources.

Related issues

Addresses [issue #121676].
Bug 121676: Hard delete custom search parameter not cleaning up all the data

Testing

Tested manually and also through adding E2E test.

FHIR Team Checklist

  • Update the title of the PR to be succinct and less than 65 characters
  • Add a milestone to the PR for the sprint that it is merged (i.e. add S47)
  • Tag the PR with the type of update: Bug, Build, Dependencies, Enhancement, New-Feature or Documentation
  • Tag the PR with Open source, Azure API for FHIR (CosmosDB or common code) or Azure Healthcare APIs (SQL or common code) to specify where this change is intended to be released.
  • Tag the PR with Schema Version backward compatible or Schema Version backward incompatible or Schema Version unchanged if this adds or updates Sql script which is/is not backward compatible with the code.
  • When changing or adding behavior, if your code modifies the system design or changes design assumptions, please create and include an ADR.
  • CI is green before merge Build Status
  • Review squash-merge requirements

Semver Change (docs)

Patch|Skip|Feature|Breaking (reason)

@tarunmathew12 tarunmathew12 added Bug Bug bug bug. Azure API for FHIR Label denotes that the issue or PR is relevant to the Azure API for FHIR Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs Open source This change is only relevant to the OSS code or release. labels May 1, 2025
@tarunmathew12 tarunmathew12 added this to the CY25Q2/2Wk02 milestone May 1, 2025
@tarunmathew12 tarunmathew12 requested a review from a team as a code owner May 1, 2025 21:56
@tarunmathew12
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tarunmathew12
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tarunmathew12
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tarunmathew12
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tarunmathew12
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tarunmathew12
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tarunmathew12
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tarunmathew12
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@@ -146,7 +143,7 @@ private async Task<IDictionary<string, long>> DeleteMultipleAsyncInternal(Condit
request.DeleteAll ? searchCount : request.MaxDeleteCount,
continuationToken,
versionType: request.VersionType,
onlyIds: true,
onlyIds: !string.Equals(request.ResourceType, KnownResourceTypes.SearchParameter, StringComparison.OrdinalIgnoreCase),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an edge case, but if this is an Includes request then this won't work. The resource type in the request is still the type of the primary resource, not the included resource. So if the search parameters are returned as part of an includes search then only the ids will be returned.
I don't know of any resource that references search parameters so I don't think this is an edge case worth covering, but I think calling it out in a comment would be good.

@@ -146,7 +143,7 @@ private async Task<IDictionary<string, long>> DeleteMultipleAsyncInternal(Condit
request.DeleteAll ? searchCount : request.MaxDeleteCount,
continuationToken,
versionType: request.VersionType,
onlyIds: true,
onlyIds: !string.Equals(request.ResourceType, KnownResourceTypes.SearchParameter, StringComparison.OrdinalIgnoreCase),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also needed on line 239

@LTA-Thinking
Copy link
Contributor

Has conditional delete been tested to see how it handles deleting search parameters?

@@ -316,5 +351,51 @@ private async Task<ITypedElement> GetSearchParameterByUrl(string url, Cancellati

return null;
}

private async Task DeleteSearchParametersAsync(List<string> urls, int pageSize, CancellationToken cancellationToken)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like how there are a DeleteSearchParameter and DeleteSearchParametersAsync methods in the same class that do different things. Could this method be DeleteSearchParametersFromDatabaseAsync? I'm not thrilled with this, but it helps show the two methods are doing different things.

@@ -174,6 +173,46 @@ public async Task UpdateSearchParameterStatusAsync(IReadOnlyCollection<string> s
await _mediator.Publish(new SearchParametersUpdatedNotification(updated), cancellationToken);
}

internal async Task UpdateSearchParameterStatusAsync(IReadOnlyCollection<ResourceSearchParameterStatus> searchParameterStatuses, CancellationToken cancellationToken)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this method needed instead of using the existing version that takes uris?

Content = CreateNotificationContent(deletedSearchParameters),
};

await _mediator.Publish(notification, cancellationToken);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern with this method of updating the search parameters is that it isn't safe if the service shuts down. If the notification isn't fully handled the DB can be left in a bad state where the Search Parameter resources are deleted, but the Search Parameter table hasn't been updated yet.


// Create search parameter resources.
await CreateAsync(resourcesToCreate);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a 1 second delay here. The bulk delete tests have been flaky when we don't wait a bit after resources are created.

@@ -532,10 +863,11 @@ private HttpRequestMessage GenerateBulkDeleteRequest(
return request;
}

private async Task MonitorBulkDeleteJob(Uri location, Dictionary<string, long> expectedResults)
private async Task MonitorBulkDeleteJob(Uri location, Dictionary<string, long> expectedResults, bool failOnIssues = false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this method updated? I don't see this new parameter being used anywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Azure API for FHIR Label denotes that the issue or PR is relevant to the Azure API for FHIR Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs Bug Bug bug bug. Open source This change is only relevant to the OSS code or release.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants