Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CustomAnalysisRules.ruleset
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
<Rule Id="CA1805" Action="Info" />
<Rule Id="CA1860" Action="Info" />
<Rule Id="CA1863" Action="Info" />
<Rule Id="CA1873" Action="None" />
<Rule Id="CA2024" Action="None" />
<Rule Id="CA2025" Action="None" />
<Rule Id="ASPDEPR008" Action="None" />
<Rule Id="ASPDEPR006" Action="None" />
<Rule Id="ASPDEPR003" Action="None" />
<Rule Id="ASPDEPR005" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
<Rule Id="CA1054" Action="Info" />
Expand Down
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
<HighEntropyVA>true</HighEntropyVA>
<LangVersion>latest</LangVersion>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<NoWarn>$(NoWarn);NU5104;CS1574;IDE0005</NoWarn>
<NoWarn>$(NoWarn);NU5104;NU1510;CS1574;IDE0005;ASPDEPR008;ASPDEPR006;ASPDEPR003;ASPDEPR005;CA2024</NoWarn>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Product>Microsoft FHIR Server for Azure</Product>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<RepositoryUrl>https://github.com/microsoft/fhir-server</RepositoryUrl>
<RunSettingsFilePath>$(MSBuildThisFileDirectory)\CodeCoverage.runsettings</RunSettingsFilePath>
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
<TargetFrameworks>net10.0;net8.0</TargetFrameworks>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
Expand Down
18 changes: 12 additions & 6 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<Project>
<!-- Shared dependencies versions.-->
<PropertyGroup>
<HealthcareSharedPackageVersion>10.0.68</HealthcareSharedPackageVersion>
<HealthcareSharedPackageVersion>11.0.3</HealthcareSharedPackageVersion>
<Hl7FhirVersion>5.11.4</Hl7FhirVersion>
<Hl7FhirLegacyVersion>5.11.0</Hl7FhirLegacyVersion>
<DotNetSdkPackageVersion>9.0.6</DotNetSdkPackageVersion>
<DotNetSdkPackageVersion>10.0.0</DotNetSdkPackageVersion>
<OpenIddictPackageVersion>6.2.0</OpenIddictPackageVersion>
</PropertyGroup>
<!-- SDK Packages -->
Expand All @@ -19,9 +19,15 @@
<AspNetPackageVersion>9.0.3</AspNetPackageVersion>
</PropertyGroup>
</When>
<When Condition="'$(TargetFramework)' == 'net10.0'">
<PropertyGroup>
<AspNetPackageVersion>10.0.0</AspNetPackageVersion>
</PropertyGroup>
</When>
</Choose>
<ItemGroup Label="CVE Mitigation">
<!--Please include the CGA id if possible-->
<PackageVersion Include="Medino.Extensions.DependencyInjection" Version="3.0.2" />
<PackageVersion Include="System.Security.Cryptography.Xml" Version="$(DotNetSdkPackageVersion)" />
<!--CVE-2023-29331-->
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="$(DotNetSdkPackageVersion)" />
Expand All @@ -34,7 +40,7 @@
</ItemGroup>
<ItemGroup>
<PackageVersion Include="AngleSharp" Version="1.2.0" />
<PackageVersion Include="Azure.Identity" Version="1.16.0" />
<PackageVersion Include="Azure.Identity" Version="1.17.0" />
<PackageVersion Include="Azure.ResourceManager.CosmosDB" Version="1.3.2" />
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.4.0" />
<PackageVersion Include="Azure.Monitor.OpenTelemetry.AspNetCore" Version="1.2.0" />
Expand All @@ -60,7 +66,7 @@
<PackageVersion Include="Hl7.Fhir.Specification.R4" Version="$(Hl7FhirVersion)" />
<PackageVersion Include="Hl7.Fhir.Specification.R4B" Version="$(Hl7FhirVersion)" />
<PackageVersion Include="Hl7.Fhir.Specification.R5" Version="$(Hl7FhirVersion)" />
<PackageVersion Include="MediatR" Version="12.5.0" />
<PackageVersion Include="Medino" Version="3.0.2" />
<PackageVersion Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(AspNetPackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.JsonPatch" Version="$(AspNetPackageVersion)" />
Expand All @@ -71,7 +77,7 @@
<PackageVersion Include="Microsoft.Azure.ContainerRegistry" Version="1.0.0-preview.2" />
<PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.48.0" />
<PackageVersion Include="Microsoft.Azure.Storage.Blob" Version="11.2.3" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="6.1.1" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="6.1.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="$(DotNetSdkPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(DotNetSdkPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="$(DotNetSdkPackageVersion)" />
Expand Down Expand Up @@ -140,4 +146,4 @@
<PackageVersion Include="Moq" Version="4.20.69" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>
</Project>
</Project>
4 changes: 2 additions & 2 deletions THIRDPARTYNOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,8 @@ This file is based on or incorporates material from the projects listed below (T
> limitations under the License.
>

## MediatR 9.0.0
* Component Source: https://github.com/jbogard/MediatR
## Medino 3.0.2
* Component Source: https://github.com/brendankowitz/Medino
* Component Copyright and License:
> Apache License
> Version 2.0, January 2004
Expand Down
3 changes: 2 additions & 1 deletion build/build-variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ variables:
buildConfiguration: 'Release'
publicDockerImagePlatforms: 'linux/amd64,linux/arm64'
testDockerImagePlatforms: 'linux/amd64'
defaultBuildFramework: 'net9.0'
# Use .NET 10 SDK to support SQL script generation tool, target net10.0
defaultBuildFramework: 'net10.0'
azureSubscriptionEndpoint: 'docker-build'
azureContainerRegistryName: 'healthplatformregistry'
azureContainerRegistry: '$(azureContainerRegistryName).azurecr.io'
Expand Down
2 changes: 1 addition & 1 deletion build/ci-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ stages:
majorMinorPatch: $[stageDependencies.UpdateVersion.Semver.outputs['SetVariablesFromGitVersion.majorMinorPatch']]
nuGetVersion: $[stageDependencies.UpdateVersion.Semver.outputs['SetVariablesFromGitVersion.nuGetVersion']]
jobs:
- job: Windows_dotnet9
- job: Windows_dotnet10
pool:
name: '$(DefaultWindowsPool)'
demands:
Expand Down
7 changes: 4 additions & 3 deletions build/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# --platform tells docker to always use the host platform for the build not the target platform. Runtime container will use target platform.
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:9.0.306-azurelinux3.0 AS build
# Use .NET 10 SDK to support SQL script generation tool, targeting net10.0 and net8.0 in builds
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:10.0.100-azurelinux3.0 AS build
ARG TARGETARCH
ARG FHIR_VERSION
ARG ASSEMBLY_VER
Expand Down Expand Up @@ -77,10 +78,10 @@ RUN dotnet restore ./src/Microsoft.Health.Fhir.${FHIR_VERSION}.Web/Microsoft.Hea

COPY . .

RUN dotnet publish /repo/src/Microsoft.Health.Fhir.${FHIR_VERSION}.Web/Microsoft.Health.Fhir.${FHIR_VERSION}.Web.csproj -o "/build" --no-restore -p:AssemblyVersion="${ASSEMBLY_VER}" -p:FileVersion="${ASSEMBLY_VER}" -p:Version="${ASSEMBLY_VER}" -f net9.0 -a $TARGETARCH
RUN dotnet publish /repo/src/Microsoft.Health.Fhir.${FHIR_VERSION}.Web/Microsoft.Health.Fhir.${FHIR_VERSION}.Web.csproj -o "/build" --no-restore -p:AssemblyVersion="${ASSEMBLY_VER}" -p:FileVersion="${ASSEMBLY_VER}" -p:Version="${ASSEMBLY_VER}" -f net10.0 -a $TARGETARCH

# Implicitly uses the target platform for the runtime image.
FROM mcr.microsoft.com/dotnet/aspnet:9.0.10-azurelinux3.0 AS runtime
FROM mcr.microsoft.com/dotnet/aspnet:10.0.0-azurelinux3.0 AS runtime

ARG FHIR_VERSION

Expand Down
2 changes: 1 addition & 1 deletion build/dotnet8-compat/global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "8.0.415"
"version": "8.0.416"
}
}
5 changes: 5 additions & 0 deletions build/dotnet9-compat/global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"sdk": {
"version": "9.0.307"
}
}
2 changes: 1 addition & 1 deletion build/jobs/analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ steps:
inputs:
userProvideBuildInfo: 'msBuildInfo'
msBuildArchitecture: 'DotNetCore'
msBuildCommandline: 'dotnet build $(Build.SourcesDirectory)/Microsoft.Health.Fhir.sln --configuration $(buildConfiguration) -p:ContinuousIntegrationBuild=true -f net9.0'
msBuildCommandline: 'dotnet build $(Build.SourcesDirectory)/Microsoft.Health.Fhir.sln --configuration $(buildConfiguration) -p:ContinuousIntegrationBuild=true -f net10.0'

- task: BinSkim@4
inputs:
Expand Down
2 changes: 1 addition & 1 deletion build/pr-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ stages:
majorMinorPatch: $[stageDependencies.UpdateVersion.Semver.outputs['SetVariablesFromGitVersion.majorMinorPatch']]
nuGetVersion: $[stageDependencies.UpdateVersion.Semver.outputs['SetVariablesFromGitVersion.nuGetVersion']]
jobs:
- job: Windows_dotnet9
- job: Windows_dotnet10
pool:
name: '$(DefaultWindowsPool)'
demands:
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "9.0.306"
"version": "10.0.100"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using EnsureThat;
using MediatR;
using Medino;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Health.Core;
Expand Down Expand Up @@ -79,7 +79,7 @@ protected virtual async Task PublishNotificationAsync(HttpContext context, Reque
apiNotification.ResourceType = fhirRequestContext.ResourceType;
apiNotification.StatusCode = (HttpStatusCode)context.Response.StatusCode;

await _mediator.Publish(apiNotification, CancellationToken.None);
await _mediator.PublishAsync(apiNotification, CancellationToken.None);
}
}
catch (Exception e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
namespace Microsoft.Health.Fhir.Api.Features.ApiNotifications
{
/// <summary>
/// A Mediatr message containing information about API responses.
/// A Medino message containing information about API responses.
/// This gets emitted by the ApiNotificationMiddleware when a response is returned by the server.
/// Consume these using Mediatr to collect stats about API responses.
/// Consume these using Medino to collect stats about API responses.
/// </summary>
public class ApiResponseNotification : IMetricsNotification
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using System.Threading;
using System.Threading.Tasks;
using EnsureThat;
using MediatR;
using Medino;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -94,7 +94,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
}
}

public Task Handle(SearchParametersInitializedNotification notification, CancellationToken cancellationToken)
public Task HandleAsync(SearchParametersInitializedNotification notification, CancellationToken cancellationToken)
{
_storageReady = true;
return Task.CompletedTask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
namespace Microsoft.Health.Fhir.Api.Features.ExceptionNotifications
{
/// <summary>
/// A MediatR message containing information about exceptions with the context of the current request.
/// Consume these using MediatR to collect stats about exceptions.
/// A Medino message containing information about exceptions with the context of the current request.
/// Consume these using Medino to collect stats about exceptions.
/// </summary>
public class ExceptionNotification : IMetricsNotification
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.Net;
using System.Threading;
using EnsureThat;
using MediatR;
using Medino;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Health.Core.Features.Context;
Expand Down Expand Up @@ -72,7 +72,7 @@ public async Task Invoke(HttpContext context)
exceptionNotification.IsRequestRateExceeded = exception.IsRequestRateExceeded();
exceptionNotification.BaseException = exception;

await _mediator.Publish(exceptionNotification, CancellationToken.None);
await _mediator.PublishAsync(exceptionNotification, CancellationToken.None);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Medino;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Health.Fhir.Core.Features.Health;

Expand All @@ -26,7 +26,7 @@ public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, Canc
return Task.FromResult(new HealthCheckResult(HealthStatus.Unhealthy, "Improper server behavior has been detected." + _message));
}

public Task Handle(ImproperBehaviorNotification notification, CancellationToken cancellationToken)
public Task HandleAsync(ImproperBehaviorNotification notification, CancellationToken cancellationToken)
{
_isHealthy = false;
_message += " " + notification.Message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.Threading;
using System.Threading.Tasks;
using EnsureThat;
using MediatR;
using Medino;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Health.Core;
using Microsoft.Health.Fhir.Core.Extensions;
Expand Down Expand Up @@ -54,7 +54,7 @@ public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, Canc
return Task.FromResult(new HealthCheckResult(HealthStatus.Unhealthy, $"Storage has not been initialized. Waited: {(int)waited.TotalSeconds}s."));
}

public Task Handle(SearchParametersInitializedNotification notification, CancellationToken cancellationToken)
public Task HandleAsync(SearchParametersInitializedNotification notification, CancellationToken cancellationToken)
{
_storageReady = true;
return Task.CompletedTask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageReference Include="Ensure.That" />
<PackageReference Include="FluentValidation" />
<PackageReference Include="Hl7.Fhir.Base" />
<PackageReference Include="MediatR" />
<PackageReference Include="Medino" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" />
<PackageReference Include="Microsoft.Extensions.Http" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Medino;
using Microsoft.Health.Core.Features.Context;
using Microsoft.Health.Fhir.Core.Features.Context;
using Microsoft.Health.Fhir.Core.Features.Operations;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -111,7 +111,7 @@ public async Task GivenUnauthorizedDeleteUser_WhenCancelationIsRequested_ThenUna
_authorizationService.CheckAccess(Arg.Any<DataActions>(), Arg.Any<CancellationToken>()).Returns(DataActions.Read);

var request = new CancelBulkDeleteRequest(1);
await Assert.ThrowsAsync<UnauthorizedFhirActionException>(async () => await _handler.Handle(request, CancellationToken.None));
await Assert.ThrowsAsync<UnauthorizedFhirActionException>(async () => await _handler.HandleAsync(request, CancellationToken.None));
}

[Fact]
Expand All @@ -121,7 +121,7 @@ public async Task GivenNonExistantBulkDeleteJob_WhenCancelationIsRequested_ThenN
_queueClient.GetJobByGroupIdAsync((byte)QueueType.BulkDelete, Arg.Any<long>(), false, Arg.Any<CancellationToken>()).Returns(new List<JobInfo>());

var request = new CancelBulkDeleteRequest(1);
await Assert.ThrowsAsync<JobNotFoundException>(async () => await _handler.Handle(request, CancellationToken.None));
await Assert.ThrowsAsync<JobNotFoundException>(async () => await _handler.HandleAsync(request, CancellationToken.None));
}

private async Task RunBulkDeleteTest(IReadOnlyList<JobInfo> jobs, HttpStatusCode expectedStatus)
Expand All @@ -134,12 +134,12 @@ private async Task RunBulkDeleteTest(IReadOnlyList<JobInfo> jobs, HttpStatusCode

if (expectedStatus == HttpStatusCode.Conflict)
{
OperationFailedException operationFailedException = await Assert.ThrowsAsync<OperationFailedException>(async () => await _handler.Handle(request, CancellationToken.None));
OperationFailedException operationFailedException = await Assert.ThrowsAsync<OperationFailedException>(async () => await _handler.HandleAsync(request, CancellationToken.None));
Assert.Equal(HttpStatusCode.Conflict, operationFailedException.ResponseStatusCode);
}
else
{
var response = await _handler.Handle(request, CancellationToken.None);
var response = await _handler.HandleAsync(request, CancellationToken.None);

Assert.Equal(expectedStatus, response.StatusCode);
if (expectedStatus == HttpStatusCode.Accepted)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -94,7 +94,7 @@ public async Task GivenBulkDeleteRequest_WhenJobCreationRequested_ThenJobIsCreat

var request = new CreateBulkDeleteRequest(DeleteOperation.HardDelete, KnownResourceTypes.Patient, searchParams, false, null, false);

var response = await _handler.Handle(request, CancellationToken.None);
var response = await _handler.HandleAsync(request, CancellationToken.None);
Assert.NotNull(response);
Assert.Equal(1, response.Id);
await _queueClient.ReceivedWithAnyArgs(1).EnqueueAsync((byte)QueueType.BulkDelete, Arg.Any<string[]>(), Arg.Any<long?>(), false, Arg.Any<CancellationToken>());
Expand All @@ -113,7 +113,7 @@ public async Task GivenBulkDeleteRequestWithInvalidSearchParameter_WhenJobCreati

var request = new CreateBulkDeleteRequest(DeleteOperation.HardDelete, KnownResourceTypes.Patient, searchParams, false, null, false);

await Assert.ThrowsAsync<BadRequestException>(async () => await _handler.Handle(request, CancellationToken.None));
await Assert.ThrowsAsync<BadRequestException>(async () => await _handler.HandleAsync(request, CancellationToken.None));
}

[Theory]
Expand All @@ -125,7 +125,7 @@ public async Task GivenUnauthorizedUser_WhenJobCreationRequested_ThenUnauthorize
_authorizationService.CheckAccess(Arg.Any<DataActions>(), Arg.Any<CancellationToken>()).Returns(userRole);

var request = new CreateBulkDeleteRequest(deleteOperation, null, null, false, null, false);
await Assert.ThrowsAsync<UnauthorizedFhirActionException>(async () => await _handler.Handle(request, CancellationToken.None));
await Assert.ThrowsAsync<UnauthorizedFhirActionException>(async () => await _handler.HandleAsync(request, CancellationToken.None));
}

[Fact]
Expand All @@ -136,7 +136,7 @@ public async Task GivenBulkDeleteRequest_WhenJobCreationFails_ThenExceptionIsThr
_queueClient.EnqueueAsync((byte)QueueType.BulkDelete, Arg.Any<string[]>(), Arg.Any<long?>(), false, Arg.Any<CancellationToken>()).Returns(new List<JobInfo>());

var request = new CreateBulkDeleteRequest(DeleteOperation.HardDelete, null, new List<Tuple<string, string>>(), false, null, false);
await Assert.ThrowsAsync<JobNotExistException>(async () => await _handler.Handle(request, CancellationToken.None));
await Assert.ThrowsAsync<JobNotExistException>(async () => await _handler.HandleAsync(request, CancellationToken.None));
}
}
}
Loading
Loading