Skip to content

Conversation

@brendankowitz
Copy link
Member

Description

This pull request migrates the project from using the MediatR library to the Medino library for in-process messaging and notifications. All usages, references, and documentation have been updated accordingly. Additionally, the minimum version of the shared healthcare package has been updated. The most significant changes are summarized below.

Dependency and Package Management:

  • Replaced the MediatR NuGet package with Medino in all project and props files, and updated the shared healthcare package version from 10.0.68 to 11.0.3. (Directory.Packages.props [1] [2]; src/Microsoft.Health.Fhir.Api/Microsoft.Health.Fhir.Api.csproj [3]

  • Updated third-party notices to reflect the switch from MediatR 9.0.0 to Medino 3.0.2. (THIRDPARTYNOTICES.md THIRDPARTYNOTICES.mdL542-R543)

Codebase Migration to Medino:

  • Replaced all using MediatR; statements with using Medino; across the codebase and tests. (src/Microsoft.Health.Fhir.Api/Features/ApiNotifications/ApiNotificationMiddleware.cs [1] src/Microsoft.Health.Fhir.Api/Features/BackgroundJobService/HostingBackgroundService.cs [2] src/Microsoft.Health.Fhir.Api/Features/ExceptionNotifications/ExceptionNotificationMiddleware.cs [3] src/Microsoft.Health.Fhir.Api/Features/Health/ImproperBehaviorHealthCheck.cs [4] src/Microsoft.Health.Fhir.Api/Features/Health/StorageInitializedHealthCheck.cs [5] src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/BulkDelete/BulkDeleteProcessingJobTests.cs [6] src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/BulkUpdate/BulkUpdateProcessingJobTests.cs [7] src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/Export/CancelExportRequestHandlerTests.cs [8]

  • Updated all code and tests to use PublishAsync instead of Publish for publishing notifications with the Medino mediator. (src/Microsoft.Health.Fhir.Api/Features/ApiNotifications/ApiNotificationMiddleware.cs [1] src/Microsoft.Health.Fhir.Api/Features/ExceptionNotifications/ExceptionNotificationMiddleware.cs [2] src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/BulkUpdate/BulkUpdateProcessingJobTests.cs [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]

Documentation and Comments:

  • Updated all class and method documentation to reference Medino instead of MediatR. (src/Microsoft.Health.Fhir.Api/Features/ApiNotifications/ApiResponseNotification.cs [1] src/Microsoft.Health.Fhir.Api/Features/ExceptionNotifications/ExceptionNotification.cs [2]

Related issues

Addresses [issue #].

Testing

Describe how this change was tested.

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)

@brendankowitz brendankowitz force-pushed the personal/bkowitz/update-healthcare-shared branch 8 times, most recently from ae54710 to e60562d Compare November 18, 2025 00:32
}

resources.AddRange(patients.Reverse());
resources.AddRange(((IEnumerable<Patient>)patients).Reverse());

Check warning

Code scanning / CodeQL

Useless upcast Warning test

There is no need to upcast from
Patient\[\]
to
IEnumerable
- the conversion can be done implicitly.

Copilot Autofix

AI 17 days ago

To fix the redundant upcast, simply remove the explicit cast on line 492. Change:

resources.AddRange(((IEnumerable<Patient>)patients).Reverse());

to:

resources.AddRange(patients.Reverse());

This works because patients is already a Patient[] (which implements IEnumerable<Patient>), and Reverse() is an extension method from LINQ for any IEnumerable<T>. No other code or imports are affected or need to be changed.

Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
@@ -489,7 +489,7 @@
                 observations.Add(obs.First());
             }
 
-            resources.AddRange(((IEnumerable<Patient>)patients).Reverse());
+            resources.AddRange(patients.Reverse());
             resources.AddRange(observations);
 
             // Ask to get all patient with specific tag order by birthdate (timestamp)
EOF
@@ -489,7 +489,7 @@
observations.Add(obs.First());
}

resources.AddRange(((IEnumerable<Patient>)patients).Reverse());
resources.AddRange(patients.Reverse());
resources.AddRange(observations);

// Ask to get all patient with specific tag order by birthdate (timestamp)
Copilot is powered by AI and may make mistakes. Always verify output.
}

resources.AddRange(patients.Reverse());
resources.AddRange(((IEnumerable<Patient>)patients).Reverse());

Check warning

Code scanning / CodeQL

Useless upcast Warning test

There is no need to upcast from
Patient\[\]
to
IEnumerable
- the conversion can be done implicitly.

Copilot Autofix

AI 17 days ago

To fix the problem, simply remove the unnecessary cast (IEnumerable<Patient>) from the code, as the patients array already implements IEnumerable<Patient>. This change will retain the same functionality as before, but will remove unnecessary verbosity and clutter from the code. Update only the line containing the explicit cast:

  • In test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs, line 564
    No additional methods or imports are needed for this fix.

Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
@@ -561,7 +561,7 @@
                 observations.Add(obs.First());
             }
 
-            resources.AddRange(((IEnumerable<Patient>)patients).Reverse());
+            resources.AddRange(patients.Reverse());
             observations.Reverse();
             resources.AddRange(observations);
 
EOF
@@ -561,7 +561,7 @@
observations.Add(obs.First());
}

resources.AddRange(((IEnumerable<Patient>)patients).Reverse());
resources.AddRange(patients.Reverse());
observations.Reverse();
resources.AddRange(observations);

Copilot is powered by AI and may make mistakes. Always verify output.

var request = new CreateExportRequest(RequestUrl, ExportJobType.All, null, formatName: formatName);
CreateExportResponse response = await _createExportRequestHandler.Handle(request, _cancellationToken);
CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
response
is useless, since its value is never read.

Copilot Autofix

AI 17 days ago

To fix this issue, we should remove the useless assignment to the local variable response. We want to preserve the await of the asynchronous method to ensure program logic and timing remains unchanged. Thus, instead of assigning to a variable, we should simply await the operation on its own. All remaining code is unchanged, since none relies on the value assigned to response. Edits are needed for both of the affected methods in the file: remove the assignment and just await the method call.

Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
@@ -386,7 +386,7 @@
                 Arg.Any<CancellationToken>());
 
             var request = new CreateExportRequest(RequestUrl, ExportJobType.All, null, formatName: formatName);
-            CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
+            await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
 
             Assert.Equal(expectedFormat, actualRecord.ExportFormat);
         }
@@ -407,7 +407,7 @@
                 Arg.Any<CancellationToken>());
 
             var request = new CreateExportRequest(RequestUrl, ExportJobType.All, containerName: containerSpecified ? "test" : null);
-            CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
+            await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
 
             Assert.Equal(expectedFormat, actualRecord.ExportFormat);
         }
EOF
@@ -386,7 +386,7 @@
Arg.Any<CancellationToken>());

var request = new CreateExportRequest(RequestUrl, ExportJobType.All, null, formatName: formatName);
CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

Assert.Equal(expectedFormat, actualRecord.ExportFormat);
}
@@ -407,7 +407,7 @@
Arg.Any<CancellationToken>());

var request = new CreateExportRequest(RequestUrl, ExportJobType.All, containerName: containerSpecified ? "test" : null);
CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

Assert.Equal(expectedFormat, actualRecord.ExportFormat);
}
Copilot is powered by AI and may make mistakes. Always verify output.

var request = new CreateExportRequest(RequestUrl, ExportJobType.All, containerName: containerSpecified ? "test" : null);
CreateExportResponse response = await _createExportRequestHandler.Handle(request, _cancellationToken);
CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
response
is useless, since its value is never read.

Copilot Autofix

AI 17 days ago

The best fix is very simple: remove the assignment of the result of _createExportRequestHandler.HandleAsync to the unused local variable response. Instead, simply await the method directly (without capturing its result), preserving proper sequencing and exception propagation, but eliminating unnecessary unused assignment. Only the assignment line itself (CreateExportResponse response = await ...) needs to be replaced with an awaited call without the variable and type declaration. No additional imports, methods, or definitions are needed.

Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
@@ -407,7 +407,7 @@
                 Arg.Any<CancellationToken>());
 
             var request = new CreateExportRequest(RequestUrl, ExportJobType.All, containerName: containerSpecified ? "test" : null);
-            CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
+            await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
 
             Assert.Equal(expectedFormat, actualRecord.ExportFormat);
         }
EOF
@@ -407,7 +407,7 @@
Arg.Any<CancellationToken>());

var request = new CreateExportRequest(RequestUrl, ExportJobType.All, containerName: containerSpecified ? "test" : null);
CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

Assert.Equal(expectedFormat, actualRecord.ExportFormat);
}
Copilot is powered by AI and may make mistakes. Always verify output.

var request = new CreateExportRequest(RequestUrl, ExportJobType.All, filters: filters);
CreateExportResponse response = await _createExportRequestHandler.Handle(request, _cancellationToken);
CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
response
is useless, since its value is never read.

Copilot Autofix

AI 17 days ago

To fix the problem, you should remove the assignment to the variable response while retaining the awaited call to _createExportRequestHandler.HandleAsync(...), in order to preserve any expected side effects or exceptions that may result from calling it. Specifically, in file test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs, in method GivenARequestWithFilters_WhenConverted_ThenTheFiltersArePopulated, replace:

CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

with:

await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

No additional imports, methods, or definitions are required.


Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Export/CreateExportRequestHandlerTests.cs
@@ -434,7 +434,7 @@
                 Arg.Any<CancellationToken>());
 
             var request = new CreateExportRequest(RequestUrl, ExportJobType.All, filters: filters);
-            CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
+            await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
 
             Assert.Collection(
                 actualRecord.Filters,
EOF
@@ -434,7 +434,7 @@
Arg.Any<CancellationToken>());

var request = new CreateExportRequest(RequestUrl, ExportJobType.All, filters: filters);
CreateExportResponse response = await _createExportRequestHandler.HandleAsync(request, _cancellationToken);
await _createExportRequestHandler.HandleAsync(request, _cancellationToken);

Assert.Collection(
actualRecord.Filters,
Copilot is powered by AI and may make mistakes. Always verify output.
}

CreateReindexResponse response = await _createReindexRequestHandler.Handle(request, CancellationToken.None);
CreateReindexResponse response = await _createReindexRequestHandler.HandleAsync(request, CancellationToken.None);

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
response
is useless, since its value is never read.

Copilot Autofix

AI 17 days ago

To fix the issue, remove the redundant assignment to the response variable and simply await the handler method for its potential side effects (most importantly, for throwing exceptions in this test). This does not affect existing functionality because response is not used after being assigned. The specific change is on line 419: replace CreateReindexResponse response = await _createReindexRequestHandler.HandleAsync(request, CancellationToken.None); with await _createReindexRequestHandler.HandleAsync(request, CancellationToken.None);.

Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Reindex/ReindexJobTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Reindex/ReindexJobTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Reindex/ReindexJobTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Reindex/ReindexJobTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.Integration/Features/Operations/Reindex/ReindexJobTests.cs
@@ -416,7 +416,7 @@
                         break;
                 }
 
-                CreateReindexResponse response = await _createReindexRequestHandler.HandleAsync(request, CancellationToken.None);
+                await _createReindexRequestHandler.HandleAsync(request, CancellationToken.None);
             }
             catch (FhirException fhirExp)
             {
EOF
@@ -416,7 +416,7 @@
break;
}

CreateReindexResponse response = await _createReindexRequestHandler.HandleAsync(request, CancellationToken.None);
await _createReindexRequestHandler.HandleAsync(request, CancellationToken.None);
}
catch (FhirException fhirExp)
{
Copilot is powered by AI and may make mistakes. Always verify output.
@brendankowitz brendankowitz force-pushed the personal/bkowitz/update-healthcare-shared branch 7 times, most recently from 7c41da5 to dc2ac20 Compare November 27, 2025 00:48
@brendankowitz
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@brendankowitz brendankowitz force-pushed the personal/bkowitz/update-healthcare-shared branch from dc2ac20 to f1158bb Compare December 2, 2025 01:09
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.

2 participants