diff --git a/build/build.yml b/build/build.yml
index 928652d8..6b9bdf2c 100644
--- a/build/build.yml
+++ b/build/build.yml
@@ -7,6 +7,8 @@ steps:
displayName: 'Use .NET Core sdk 6.0.x'
inputs:
version: 6.0.x
+ selectOrConfig: configs
+ nugetConfigPath: nuget.config
- script: dotnet build --configuration $(buildConfiguration) --version-suffix $(build.buildNumber) /warnaserror
displayName: 'dotnet build $(buildConfiguration)'
diff --git a/nuget.config b/nuget.config
new file mode 100644
index 00000000..47ede985
--- /dev/null
+++ b/nuget.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/console/MeasurementCollectionToFhir/ProcessorStartup.cs b/src/console/MeasurementCollectionToFhir/ProcessorStartup.cs
index e1350b08..21ba1a6f 100644
--- a/src/console/MeasurementCollectionToFhir/ProcessorStartup.cs
+++ b/src/console/MeasurementCollectionToFhir/ProcessorStartup.cs
@@ -1,6 +1,5 @@
using EnsureThat;
using Hl7.Fhir.Model;
-using Hl7.Fhir.Rest;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -10,6 +9,7 @@
using Microsoft.Health.Common;
using Microsoft.Health.Extensions.Fhir;
using Microsoft.Health.Extensions.Fhir.Config;
+using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Config;
using Microsoft.Health.Fhir.Ingest.Host;
using Microsoft.Health.Fhir.Ingest.Service;
@@ -38,13 +38,15 @@ public void ConfigureServices(IServiceCollection services)
services.Configure(Configuration.GetSection("ResourceIdentity"));
services.Configure(Configuration.GetSection("FhirClient"));
- services.TryAddSingleton, FhirClientFactory>();
- services.TryAddSingleton(sp => sp.GetRequiredService>().Create());
- services.TryAddSingleton, Observation>, R4FhirLookupTemplateProcessor>();
+ services.AddFhirClient(Configuration);
services.TryAddSingleton(ResolveResourceIdentityService);
+ services.TryAddSingleton();
+
+ services.TryAddSingleton, Observation>, R4FhirLookupTemplateProcessor>();
services.TryAddSingleton(sp => new MemoryCache(Options.Create(new MemoryCacheOptions { SizeLimit = 5000 })));
services.TryAddSingleton();
+ services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton(ResolveMeasurementImportProvider);
@@ -65,9 +67,9 @@ private static IResourceIdentityService ResolveResourceIdentityService(IServiceP
{
EnsureArg.IsNotNull(serviceProvider, nameof(serviceProvider));
- var fhirClient = serviceProvider.GetRequiredService();
+ var fhirService = serviceProvider.GetRequiredService();
var resourceIdentityOptions = serviceProvider.GetRequiredService>();
- return ResourceIdentityServiceFactory.Instance.Create(resourceIdentityOptions.Value, fhirClient);
+ return ResourceIdentityServiceFactory.Instance.Create(resourceIdentityOptions.Value, fhirService);
}
}
}
diff --git a/src/console/Microsoft.Health.Fhir.Ingest.Console.csproj b/src/console/Microsoft.Health.Fhir.Ingest.Console.csproj
index 07d3917a..82dc6079 100644
--- a/src/console/Microsoft.Health.Fhir.Ingest.Console.csproj
+++ b/src/console/Microsoft.Health.Fhir.Ingest.Console.csproj
@@ -20,6 +20,7 @@
+
diff --git a/src/func/Microsoft.Health.Fhir.Ingest.Host/Microsoft.Health.Fhir.Ingest.Host.csproj b/src/func/Microsoft.Health.Fhir.Ingest.Host/Microsoft.Health.Fhir.Ingest.Host.csproj
index e93f9985..c7231c63 100644
--- a/src/func/Microsoft.Health.Fhir.Ingest.Host/Microsoft.Health.Fhir.Ingest.Host.csproj
+++ b/src/func/Microsoft.Health.Fhir.Ingest.Host/Microsoft.Health.Fhir.Ingest.Host.csproj
@@ -35,7 +35,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/BearerTokenAuthorizationMessageHandler.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/BearerTokenAuthorizationMessageHandler.cs
new file mode 100644
index 00000000..573b19d4
--- /dev/null
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/BearerTokenAuthorizationMessageHandler.cs
@@ -0,0 +1,54 @@
+// -------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
+// -------------------------------------------------------------------------------------------------
+
+using System;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.Core;
+using EnsureThat;
+using Microsoft.Health.Common.Telemetry;
+using Microsoft.Health.Extensions.Fhir.Telemetry.Metrics;
+using Microsoft.Health.Logging.Telemetry;
+
+namespace Microsoft.Health.Extensions.Fhir
+{
+ public class BearerTokenAuthorizationMessageHandler : DelegatingHandler
+ {
+ public BearerTokenAuthorizationMessageHandler(Uri uri, TokenCredential tokenCredentialProvider, ITelemetryLogger logger)
+ {
+ TokenCredential = EnsureArg.IsNotNull(tokenCredentialProvider, nameof(tokenCredentialProvider));
+ Uri = EnsureArg.IsNotNull(uri, nameof(uri));
+ Logger = EnsureArg.IsNotNull(logger, nameof(logger));
+ Scopes = new string[] { Uri.ToString().EndsWith(@"/") ? Uri + ".default" : Uri + "/.default" };
+ }
+
+ private ITelemetryLogger Logger { get; }
+
+ private TokenCredential TokenCredential { get; }
+
+ private Uri Uri { get; }
+
+ private string[] Scopes { get; }
+
+ protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ var requestContext = new TokenRequestContext(Scopes);
+ var accessToken = await TokenCredential.GetTokenAsync(requestContext, cancellationToken);
+ request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Token);
+ var response = await base.SendAsync(request, cancellationToken);
+
+ if (!response.IsSuccessStatusCode)
+ {
+ var statusDescription = response.ReasonPhrase.Replace(" ", string.Empty);
+ var severity = response.StatusCode == System.Net.HttpStatusCode.TooManyRequests ? ErrorSeverity.Informational : ErrorSeverity.Critical;
+ Logger.LogMetric(FhirClientMetrics.HandledException($"{ErrorType.FHIRServiceError}{statusDescription}", severity), 1);
+ }
+
+ return response;
+ }
+ }
+}
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/BundleExtensions.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/BundleExtensions.cs
index d41778bf..143f05d4 100644
--- a/src/lib/Microsoft.Health.Extensions.Fhir.R4/BundleExtensions.cs
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/BundleExtensions.cs
@@ -9,7 +9,7 @@
using System.Threading.Tasks;
using EnsureThat;
using Hl7.Fhir.Model;
-using Hl7.Fhir.Rest;
+using Microsoft.Health.Extensions.Fhir.Service;
namespace Microsoft.Health.Extensions.Fhir
{
@@ -41,7 +41,10 @@ public static IEnumerable ReadFromBundle(this Bundle bundl
}
}
- public static async Task ReadOneFromBundleWithContinuationAsync(this Bundle bundle, FhirClient fhirClient, bool throwOnMultipleFound = true)
+ public static async Task ReadOneFromBundleWithContinuationAsync(
+ this Bundle bundle,
+ IFhirService fhirService,
+ bool throwOnMultipleFound = true)
where TResource : Resource, new()
{
if (bundle == null)
@@ -49,7 +52,7 @@ public static async Task ReadOneFromBundleWithContinuationAsync(fhirClient, 2);
+ var resources = await bundle?.ReadFromBundleWithContinuationAsync(fhirService, 2);
var resourceCount = resources.Count();
if (resourceCount == 0)
@@ -75,13 +78,17 @@ public static int EntryCount(this Bundle bundle)
return bundle?.Entry?.Count ?? 0;
}
- public static async Task> ReadFromBundleWithContinuationAsync(this Bundle bundle, FhirClient fhirClient, int? count = null)
+ private static async Task> ReadFromBundleWithContinuationAsync(
+ this Bundle bundle,
+ IFhirService fhirService,
+ int? count = null)
where TResource : Resource
{
- EnsureArg.IsNotNull(fhirClient, nameof(fhirClient));
+ EnsureArg.IsNotNull(fhirService, nameof(fhirService));
var resources = new List();
- while (bundle != null)
+
+ Action storeResources = (bundle) =>
{
foreach (var r in bundle.ReadFromBundle(count))
{
@@ -96,30 +103,16 @@ public static async Task> ReadFromBundleWithContinuationA
count--;
}
}
+ };
+
+ storeResources.Invoke(bundle);
- bundle = await fhirClient.ContinueAsync(bundle).ConfigureAwait(false);
+ await foreach (var currentBundle in fhirService.IterateOverAdditionalBundlesAsync(bundle))
+ {
+ storeResources.Invoke(currentBundle);
}
return resources;
}
-
- public static async Task> SearchWithContinuationAsync(this FhirClient fhirClient, SearchParams searchParams)
- where TResource : Resource
- {
- EnsureArg.IsNotNull(fhirClient, nameof(fhirClient));
- EnsureArg.IsNotNull(searchParams, nameof(searchParams));
-
- var result = await fhirClient.SearchAsync(searchParams).ConfigureAwait(false);
- return await result.ReadFromBundleWithContinuationAsync(fhirClient, searchParams.Count).ConfigureAwait(false);
- }
-
- public static async Task> GetWithContinuationAsync(this FhirClient fhirClient, Uri resourceUri, int? count = null)
- where TResource : Resource
- {
- EnsureArg.IsNotNull(fhirClient, nameof(fhirClient));
-
- var result = await fhirClient.GetAsync(resourceUri).ConfigureAwait(false) as Bundle;
- return await result.ReadFromBundleWithContinuationAsync(fhirClient, count).ConfigureAwait(false);
- }
}
}
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirClientFactory.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirClientFactory.cs
deleted file mode 100644
index f5c4772a..00000000
--- a/src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirClientFactory.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-// -------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
-// -------------------------------------------------------------------------------------------------
-
-using System;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Threading;
-using System.Threading.Tasks;
-using Azure.Core;
-using EnsureThat;
-using Hl7.Fhir.Rest;
-using Microsoft.Extensions.Options;
-using Microsoft.Health.Common;
-using Microsoft.Health.Common.Auth;
-using Microsoft.Health.Common.Telemetry;
-using Microsoft.Health.Extensions.Fhir.Config;
-using Microsoft.Health.Extensions.Fhir.Telemetry.Exceptions;
-using Microsoft.Health.Extensions.Fhir.Telemetry.Metrics;
-using Microsoft.Health.Extensions.Host.Auth;
-using Microsoft.Health.Logging.Telemetry;
-
-namespace Microsoft.Health.Extensions.Fhir
-{
- public class FhirClientFactory : IFactory
- {
- private readonly bool _useManagedIdentity = false;
- private readonly IAzureCredentialProvider _tokenCredentialProvider;
- private readonly ITelemetryLogger _logger;
-
- public FhirClientFactory(IOptions options, ITelemetryLogger logger)
- : this(EnsureArg.IsNotNull(options, nameof(options)).Value.UseManagedIdentity, logger)
- {
- }
-
- private FhirClientFactory()
- : this(useManagedIdentity: false, logger: null)
- {
- }
-
- private FhirClientFactory(bool useManagedIdentity, ITelemetryLogger logger)
- {
- _useManagedIdentity = useManagedIdentity;
- _logger = logger;
- }
-
- public FhirClientFactory(IAzureCredentialProvider provider, ITelemetryLogger logger)
- {
- _tokenCredentialProvider = provider;
- _logger = logger;
- }
-
- public static IFactory Instance { get; } = new FhirClientFactory();
-
- public FhirClient Create()
- {
- if (_tokenCredentialProvider != null)
- {
- return CreateClient(_tokenCredentialProvider.GetCredential(), _logger);
- }
-
- return _useManagedIdentity ? CreateManagedIdentityClient(_logger) : CreateConfidentialApplicationClient(_logger);
- }
-
- private static FhirClient CreateClient(TokenCredential tokenCredential, ITelemetryLogger logger)
- {
- EnsureArg.IsNotNull(tokenCredential, nameof(tokenCredential));
-
- var url = Environment.GetEnvironmentVariable("FhirService:Url");
- EnsureArg.IsNotNullOrEmpty(url, nameof(url));
- var uri = new Uri(url);
-
- var fhirClientSettings = new FhirClientSettings
- {
- PreferredFormat = ResourceFormat.Json,
- };
-
- FhirClient client = null;
- try
- {
- client = new FhirClient(url, fhirClientSettings, new BearerTokenAuthorizationMessageHandler(uri, tokenCredential, logger));
- FhirServiceValidator.ValidateFhirService(client, logger);
- }
- catch (Exception ex)
- {
- FhirServiceExceptionProcessor.ProcessException(ex, logger);
- }
-
- return client;
- }
-
- private static FhirClient CreateManagedIdentityClient(ITelemetryLogger logger)
- {
- return CreateClient(new ManagedIdentityAuthService(), logger);
- }
-
- private static FhirClient CreateConfidentialApplicationClient(ITelemetryLogger logger)
- {
- return CreateClient(new OAuthConfidentialClientAuthService(), logger);
- }
-
- private class BearerTokenAuthorizationMessageHandler : HttpClientHandler
- {
- public BearerTokenAuthorizationMessageHandler(Uri uri, TokenCredential tokenCredentialProvider, ITelemetryLogger logger)
- {
- TokenCredential = EnsureArg.IsNotNull(tokenCredentialProvider, nameof(tokenCredentialProvider));
- Uri = EnsureArg.IsNotNull(uri);
- Scopes = new string[] { Uri + ".default" };
- Logger = logger;
- }
-
- private ITelemetryLogger Logger { get; }
-
- private TokenCredential TokenCredential { get; }
-
- private Uri Uri { get; }
-
- private string[] Scopes { get; }
-
- protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
- {
- var requestContext = new TokenRequestContext(Scopes);
- var accessToken = await TokenCredential.GetTokenAsync(requestContext, CancellationToken.None);
- request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Token);
- var response = await base.SendAsync(request, cancellationToken);
-
- if (Logger != null && !response.IsSuccessStatusCode)
- {
- var statusDescription = response.ReasonPhrase.Replace(" ", string.Empty);
- var severity = response.StatusCode == System.Net.HttpStatusCode.TooManyRequests ? ErrorSeverity.Informational : ErrorSeverity.Critical;
- Logger.LogMetric(FhirClientMetrics.HandledException($"{ErrorType.FHIRServiceError}{statusDescription}", severity), 1);
- }
-
- return response;
- }
- }
- }
-}
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirServiceValidator.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirClientValidator.cs
similarity index 67%
rename from src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirServiceValidator.cs
rename to src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirClientValidator.cs
index 09acfa7b..3461d967 100644
--- a/src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirServiceValidator.cs
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/FhirClientValidator.cs
@@ -4,22 +4,26 @@
// -------------------------------------------------------------------------------------------------
using System;
+using System.Threading.Tasks;
using EnsureThat;
-using Hl7.Fhir.Rest;
using Microsoft.Health.Extensions.Fhir.Telemetry.Exceptions;
+using Microsoft.Health.Fhir.Client;
using Microsoft.Health.Logging.Telemetry;
namespace Microsoft.Health.Extensions.Fhir
{
- public static class FhirServiceValidator
+ public static class FhirClientValidator
{
- public static bool ValidateFhirService(FhirClient client, ITelemetryLogger logger)
+ public static async Task ValidateFhirClientAsync(
+ this IFhirClient client,
+ ITelemetryLogger logger)
{
EnsureArg.IsNotNull(client, nameof(client));
+ EnsureArg.IsNotNull(logger, nameof(logger));
try
{
- client.CapabilityStatement(SummaryType.True);
+ await client.ReadAsync("metadata?_summary=true").ConfigureAwait(false);
return true;
}
catch (Exception exception)
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/HttpClientBuilderRegistrationExtensions.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/HttpClientBuilderRegistrationExtensions.cs
new file mode 100644
index 00000000..a334f275
--- /dev/null
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/HttpClientBuilderRegistrationExtensions.cs
@@ -0,0 +1,42 @@
+// -------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
+// -------------------------------------------------------------------------------------------------
+
+using System;
+using EnsureThat;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Health.Extensions.Host.Auth;
+using Microsoft.Health.Logging.Telemetry;
+
+namespace Microsoft.Health.Extensions.Fhir
+{
+ public static class HttpClientBuilderRegistrationExtensions
+ {
+ public static void AddAuthenticationHandler(
+ this IHttpClientBuilder httpClientBuilder,
+ IServiceCollection services,
+ ITelemetryLogger logger,
+ Uri uri,
+ bool useManagedIdentity)
+ {
+ EnsureArg.IsNotNull(httpClientBuilder, nameof(httpClientBuilder));
+ EnsureArg.IsNotNull(services, nameof(services));
+ EnsureArg.IsNotNull(logger, nameof(logger));
+ EnsureArg.IsNotNull(uri, nameof(uri));
+
+ if (useManagedIdentity)
+ {
+ services.AddNamedManagedIdentityCredentialProvider();
+ httpClientBuilder.AddHttpMessageHandler(x =>
+ new BearerTokenAuthorizationMessageHandler(uri, new ManagedIdentityAuthService(), logger));
+ }
+ else
+ {
+ services.AddNamedOAuth2ClientCredentialProvider();
+ httpClientBuilder.AddHttpMessageHandler(x =>
+ new BearerTokenAuthorizationMessageHandler(uri, new OAuthConfidentialClientAuthService(), logger));
+ }
+ }
+ }
+}
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Microsoft.Health.Extensions.Fhir.R4.csproj b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Microsoft.Health.Extensions.Fhir.R4.csproj
index 0b0a51dd..1196f8ee 100644
--- a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Microsoft.Health.Extensions.Fhir.R4.csproj
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Microsoft.Health.Extensions.Fhir.R4.csproj
@@ -1,39 +1,44 @@
-
- net6.0
- ..\..\..\CustomAnalysisRules.ruleset
- true
- 7.3
-
-
- true
-
-
- true
-
- Microsoft.Health.Extensions.Fhir
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
+
+ net6.0
+ ..\..\..\CustomAnalysisRules.ruleset
+ true
+ 10.0
+
+
+ true
+
+
+ true
+
+ Microsoft.Health.Extensions.Fhir
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Search/SearchExtensions.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Search/SearchExtensions.cs
index a4e9a742..14ba7701 100644
--- a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Search/SearchExtensions.cs
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Search/SearchExtensions.cs
@@ -190,5 +190,12 @@ public static string ToSearchToken(this Hl7.Fhir.Model.Identifier identifier)
token += identifier.Value;
return token;
}
+
+ public static string ToSearchQueryParameter(this Hl7.Fhir.Model.Identifier identifier)
+ {
+ EnsureArg.IsNotNull(identifier, nameof(identifier));
+
+ return $"identifier={identifier.ToSearchToken()}";
+ }
}
}
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/FhirService.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/FhirService.cs
new file mode 100644
index 00000000..41d9e110
--- /dev/null
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/FhirService.cs
@@ -0,0 +1,97 @@
+// -------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
+// -------------------------------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+using EnsureThat;
+using Hl7.Fhir.Model;
+using IFhirClient = Microsoft.Health.Fhir.Client.IFhirClient;
+
+namespace Microsoft.Health.Extensions.Fhir.Service
+{
+ public class FhirService : IFhirService
+ {
+ private readonly IFhirClient _fhirClient;
+
+ public FhirService(IFhirClient fhirClient)
+ {
+ _fhirClient = EnsureArg.IsNotNull(fhirClient, nameof(fhirClient));
+ }
+
+ public async Task CreateResourceAsync(
+ T resource,
+ string conditionalCreateCriteria = null,
+ string provenanceHeader = null,
+ CancellationToken cancellationToken = default)
+ where T : Resource
+ {
+ EnsureArg.IsNotNull(resource, nameof(resource));
+
+ return await _fhirClient.CreateAsync(resource, conditionalCreateCriteria, provenanceHeader, cancellationToken).ConfigureAwait(false);
+ }
+
+ public async Task SearchForResourceAsync(
+ ResourceType resourceType,
+ string query = null,
+ int? count = null,
+ CancellationToken cancellationToken = default)
+ {
+ EnsureArg.IsNotNull(resourceType, nameof(resourceType));
+
+ return await _fhirClient.SearchAsync(resourceType, query, count, cancellationToken).ConfigureAwait(false);
+ }
+
+ public async Task ReadResourceAsync(
+ ResourceType resourceType,
+ string resourceId,
+ CancellationToken cancellationToken = default)
+ where T : Resource
+ {
+ EnsureArg.IsNotNull(resourceType, nameof(resourceType));
+ EnsureArg.IsNotNullOrWhiteSpace(resourceId, nameof(resourceId));
+
+ return await _fhirClient.ReadAsync(resourceType, resourceId, cancellationToken).ConfigureAwait(false);
+ }
+
+ public async Task ReadResourceAsync(
+ string uri,
+ CancellationToken cancellationToken = default)
+ where T : Resource
+ {
+ EnsureArg.IsNotNullOrWhiteSpace(uri, nameof(uri));
+
+ return await _fhirClient.ReadAsync(uri, cancellationToken).ConfigureAwait(false);
+ }
+
+ public async Task UpdateResourceAsync(
+ T resource,
+ string ifMatchVersion = null,
+ string provenanceHeader = null,
+ CancellationToken cancellationToken = default)
+ where T : Resource
+ {
+ EnsureArg.IsNotNull(resource, nameof(resource));
+
+ return await _fhirClient.UpdateAsync(resource, ifMatchVersion, provenanceHeader, cancellationToken).ConfigureAwait(false);
+ }
+
+ public async IAsyncEnumerable IterateOverAdditionalBundlesAsync(
+ Bundle bundle,
+ [EnumeratorCancellation] CancellationToken cancellationToken = default)
+ {
+ Bundle nextBundle = bundle;
+ while (nextBundle?.NextLink != null)
+ {
+ nextBundle = await _fhirClient.SearchAsync(bundle.NextLink.ToString(), cancellationToken).ConfigureAwait(false);
+ if (nextBundle != null)
+ {
+ yield return nextBundle;
+ }
+ }
+ }
+ }
+}
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/IFhirService.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/IFhirService.cs
new file mode 100644
index 00000000..70a78c76
--- /dev/null
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/IFhirService.cs
@@ -0,0 +1,38 @@
+// -------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
+// -------------------------------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Hl7.Fhir.Model;
+
+namespace Microsoft.Health.Extensions.Fhir.Service
+{
+ public interface IFhirService
+ {
+ Task CreateResourceAsync(T resource, string conditionalCreateCriteria = null, string provenanceHeader = null, CancellationToken cancellationToken = default(CancellationToken))
+ where T : Resource;
+
+ Task SearchForResourceAsync(ResourceType resourceType, string query = null, int? count = null, CancellationToken cancellationToken = default(CancellationToken));
+
+ Task ReadResourceAsync(ResourceType resourceType, string resourceId, CancellationToken cancellationToken = default(CancellationToken))
+ where T : Resource;
+
+ Task ReadResourceAsync(string uri, CancellationToken cancellationToken = default(CancellationToken))
+ where T : Resource;
+
+ Task UpdateResourceAsync(T resource, string ifMatchVersion = null, string provenanceHeader = null, CancellationToken cancellationToken = default)
+ where T : Resource;
+
+ ///
+ /// Produces an iterator over additional Bundles associated with the passed Bundle. The original Bundle is not returned. The
+ /// iterator completes when there are no more pages in the Bundle
+ ///
+ /// The Bundle to begin iterating over
+ /// The cancellation token
+ /// A collection of Bundles associated with the supplied Bundle
+ IAsyncEnumerable IterateOverAdditionalBundlesAsync(Bundle bundle, CancellationToken cancellationToken = default(CancellationToken));
+ }
+}
\ No newline at end of file
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/ResourceManagementService.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/ResourceManagementService.cs
index 33089a6f..0c0420c6 100644
--- a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/ResourceManagementService.cs
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Service/ResourceManagementService.cs
@@ -6,7 +6,7 @@
using System;
using System.Threading.Tasks;
using EnsureThat;
-using Hl7.Fhir.Rest;
+using Hl7.Fhir.Model;
using Microsoft.Health.Extensions.Fhir.Search;
using Model = Hl7.Fhir.Model;
@@ -14,56 +14,62 @@ namespace Microsoft.Health.Extensions.Fhir.Service
{
public class ResourceManagementService
{
+ public ResourceManagementService(IFhirService fhirService)
+ {
+ FhirService = EnsureArg.IsNotNull(fhirService, nameof(fhirService));
+ }
+
+ public IFhirService FhirService { get; private set; }
+
///
/// Gets or creates the FHIR Resource with the provided identifier.
///
/// The type of FHIR resource to ensure exists.
- /// Client to use for FHIR rest calls.
/// The identifier value to search for or create.
/// The system the identifier belongs to.
/// Optional setter to provide property values if the resource needs to be created.
/// Reource that was found or created.
- public virtual async Task EnsureResourceByIdentityAsync(FhirClient client, string value, string system, Action propertySetter = null)
+ public virtual async Task EnsureResourceByIdentityAsync(string value, string system, Action propertySetter = null)
where TResource : Model.Resource, new()
{
- EnsureArg.IsNotNull(client, nameof(client));
EnsureArg.IsNotNullOrWhiteSpace(value, nameof(value));
var identifier = BuildIdentifier(value, system);
- return await GetResourceByIdentityAsync(client, identifier).ConfigureAwait(false)
- ?? await CreateResourceByIdentityAsync(client, identifier, propertySetter).ConfigureAwait(false);
+ return await GetResourceByIdentityAsync(identifier).ConfigureAwait(false)
+ ?? await CreateResourceByIdentityAsync(identifier, propertySetter).ConfigureAwait(false);
}
- public virtual async Task GetResourceByIdentityAsync(FhirClient client, string value, string system)
+ public virtual async Task GetResourceByIdentityAsync(string value, string system)
where TResource : Model.Resource, new()
{
- EnsureArg.IsNotNull(client, nameof(client));
EnsureArg.IsNotNullOrWhiteSpace(value, nameof(value));
var identifier = BuildIdentifier(value, system);
- return await GetResourceByIdentityAsync(client, identifier).ConfigureAwait(false);
+ return await GetResourceByIdentityAsync(identifier).ConfigureAwait(false);
}
- protected static async Task GetResourceByIdentityAsync(FhirClient client, Model.Identifier identifier)
+ protected async Task GetResourceByIdentityAsync(Model.Identifier identifier)
where TResource : Model.Resource, new()
{
- EnsureArg.IsNotNull(client, nameof(client));
EnsureArg.IsNotNull(identifier, nameof(identifier));
- var searchParams = identifier.ToSearchParams();
- var result = await client.SearchAsync(searchParams).ConfigureAwait(false);
- return await result.ReadOneFromBundleWithContinuationAsync(client);
+
+ string fhirTypeName = ModelInfo.GetFhirTypeNameForType(typeof(TResource));
+
+ _ = Enum.TryParse(fhirTypeName, out ResourceType resourceType);
+
+ Model.Bundle result = await FhirService.SearchForResourceAsync(resourceType, identifier.ToSearchQueryParameter()).ConfigureAwait(false);
+ return await result.ReadOneFromBundleWithContinuationAsync(FhirService);
}
- protected static async Task CreateResourceByIdentityAsync(FhirClient client, Model.Identifier identifier, Action propertySetter)
+ protected async Task CreateResourceByIdentityAsync(Model.Identifier identifier, Action propertySetter)
where TResource : Model.Resource, new()
{
- EnsureArg.IsNotNull(client, nameof(client));
EnsureArg.IsNotNull(identifier, nameof(identifier));
var resource = new TResource();
propertySetter?.Invoke(resource, identifier);
- return await client.CreateAsync(resource).ConfigureAwait(false);
+ return await FhirService.CreateResourceAsync(resource).ConfigureAwait(false);
}
private static Model.Identifier BuildIdentifier(string value, string system)
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/ServiceCollectionExtensions.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/ServiceCollectionExtensions.cs
new file mode 100644
index 00000000..0fdc7860
--- /dev/null
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/ServiceCollectionExtensions.cs
@@ -0,0 +1,59 @@
+// -------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
+// -------------------------------------------------------------------------------------------------
+
+using System;
+using EnsureThat;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Health.Extensions.Host.Auth;
+using Microsoft.Health.Logging.Telemetry;
+using FhirClient = Microsoft.Health.Fhir.Client.FhirClient;
+using IFhirClient = Microsoft.Health.Fhir.Client.IFhirClient;
+
+namespace Microsoft.Health.Extensions.Fhir
+{
+ public static class ServiceCollectionExtensions
+ {
+ public static void AddFhirClient(this IServiceCollection serviceCollection, IConfiguration configuration)
+ {
+ EnsureArg.IsNotNull(serviceCollection, nameof(serviceCollection));
+ EnsureArg.IsNotNull(configuration, nameof(configuration));
+
+ var url = new Uri(configuration.GetValue("FhirService:Url"));
+ bool useManagedIdentity = configuration.GetValue("FhirClient:UseManagedIdentity");
+
+ serviceCollection.AddSingleton(typeof(ITelemetryLogger), typeof(IomtTelemetryLogger));
+ var serviceProvider = serviceCollection.BuildServiceProvider();
+ var logger = serviceProvider.GetRequiredService();
+
+ serviceCollection.AddHttpClient(client =>
+ {
+ client.BaseAddress = url;
+ client.Timeout = TimeSpan.FromSeconds(60);
+
+ // Using discard because we don't need result
+ var fhirClient = new FhirClient(client);
+ _ = fhirClient.ValidateFhirClientAsync(logger);
+ return fhirClient;
+ })
+ .AddAuthenticationHandler(serviceCollection, logger, url, useManagedIdentity);
+ }
+
+ public static void AddNamedManagedIdentityCredentialProvider(this IServiceCollection serviceCollection)
+ {
+ EnsureArg.IsNotNull(serviceCollection, nameof(serviceCollection));
+
+ serviceCollection.TryAddSingleton();
+ }
+
+ public static void AddNamedOAuth2ClientCredentialProvider(this IServiceCollection serviceCollection)
+ {
+ EnsureArg.IsNotNull(serviceCollection, nameof(serviceCollection));
+
+ serviceCollection.TryAddSingleton();
+ }
+ }
+}
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Telemetry/Exceptions/FhirServiceExceptionProcessor.cs b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Telemetry/Exceptions/FhirServiceExceptionProcessor.cs
index 020b577a..d0e0df0d 100644
--- a/src/lib/Microsoft.Health.Extensions.Fhir.R4/Telemetry/Exceptions/FhirServiceExceptionProcessor.cs
+++ b/src/lib/Microsoft.Health.Extensions.Fhir.R4/Telemetry/Exceptions/FhirServiceExceptionProcessor.cs
@@ -7,10 +7,10 @@
using System.Net;
using System.Net.Http;
using EnsureThat;
-using Hl7.Fhir.Rest;
using Microsoft.Health.Common.Telemetry;
using Microsoft.Health.Extensions.Fhir.Resources;
using Microsoft.Health.Extensions.Fhir.Telemetry.Metrics;
+using Microsoft.Health.Fhir.Client;
using Microsoft.Health.Logging.Telemetry;
using Microsoft.Identity.Client;
@@ -41,8 +41,8 @@ public static (Exception customException, string errorName) CustomizeException(E
switch (exception)
{
- case FhirOperationException _:
- var status = ((FhirOperationException)exception).Status;
+ case FhirException _:
+ var status = ((FhirException)exception).StatusCode;
switch (status)
{
case HttpStatusCode.Forbidden:
@@ -75,7 +75,7 @@ public static (Exception customException, string errorName) CustomizeException(E
return (new InvalidFhirServiceException(message, exception, errorName), errorName);
case HttpRequestException _:
- // TODO: In .NET 5 and later, check HttpRequestException's StatusCode property instead of the Message property
+
if (exception.Message.Contains(FhirResources.HttpRequestErrorNotKnown, StringComparison.CurrentCultureIgnoreCase))
{
message = FhirResources.FhirServiceHttpRequestError;
@@ -83,7 +83,8 @@ public static (Exception customException, string errorName) CustomizeException(E
return (new InvalidFhirServiceException(message, exception, errorName), errorName);
}
- return (exception, nameof(FhirServiceErrorCode.HttpRequestError));
+ var statusCode = ((HttpRequestException)exception).StatusCode;
+ return (exception, $"{FhirServiceErrorCode.HttpRequestError}{statusCode}");
case MsalServiceException _:
var errorCode = ((MsalServiceException)exception).ErrorCode;
diff --git a/src/lib/Microsoft.Health.Extensions.Fhir/Microsoft.Health.Extensions.Fhir.csproj b/src/lib/Microsoft.Health.Extensions.Fhir/Microsoft.Health.Extensions.Fhir.csproj
index b490fa34..bc0fa4d5 100644
--- a/src/lib/Microsoft.Health.Extensions.Fhir/Microsoft.Health.Extensions.Fhir.csproj
+++ b/src/lib/Microsoft.Health.Extensions.Fhir/Microsoft.Health.Extensions.Fhir.csproj
@@ -16,7 +16,9 @@
-
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -29,6 +31,7 @@
+
diff --git a/src/lib/Microsoft.Health.Fhir.Ingest.Validation/Microsoft.Health.Fhir.Ingest.Validation.csproj b/src/lib/Microsoft.Health.Fhir.Ingest.Validation/Microsoft.Health.Fhir.Ingest.Validation.csproj
index 37815313..932efa93 100644
--- a/src/lib/Microsoft.Health.Fhir.Ingest.Validation/Microsoft.Health.Fhir.Ingest.Validation.csproj
+++ b/src/lib/Microsoft.Health.Fhir.Ingest.Validation/Microsoft.Health.Fhir.Ingest.Validation.csproj
@@ -19,8 +19,8 @@
true
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -32,7 +32,7 @@
-
+
diff --git a/src/lib/Microsoft.Health.Fhir.Ingest/Microsoft.Health.Fhir.Ingest.csproj b/src/lib/Microsoft.Health.Fhir.Ingest/Microsoft.Health.Fhir.Ingest.csproj
index 6a1b4699..4d3be2bc 100644
--- a/src/lib/Microsoft.Health.Fhir.Ingest/Microsoft.Health.Fhir.Ingest.csproj
+++ b/src/lib/Microsoft.Health.Fhir.Ingest/Microsoft.Health.Fhir.Ingest.csproj
@@ -5,7 +5,7 @@
true
Microsoft.Health.Fhir.Ingest
Microsoft.Health.Fhir.Ingest
- 7.3
+ 10.0
true
@@ -18,14 +18,14 @@
true
-
+
-
-
+
+
all
diff --git a/src/lib/Microsoft.Health.Fhir.Ingest/Service/ResourceIdentityServiceFactory.cs b/src/lib/Microsoft.Health.Fhir.Ingest/Service/ResourceIdentityServiceFactory.cs
index 7464355d..51e4e05b 100644
--- a/src/lib/Microsoft.Health.Fhir.Ingest/Service/ResourceIdentityServiceFactory.cs
+++ b/src/lib/Microsoft.Health.Fhir.Ingest/Service/ResourceIdentityServiceFactory.cs
@@ -88,4 +88,4 @@ private static IDictionary GetResourceIdentityServiceRegistry()
return serviceTypeRegistry;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Host/FhirHealthCheckExtensions.cs b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Host/FhirHealthCheckExtensions.cs
index 1a84fe56..5e54ed4b 100644
--- a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Host/FhirHealthCheckExtensions.cs
+++ b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Host/FhirHealthCheckExtensions.cs
@@ -4,14 +4,13 @@
// -------------------------------------------------------------------------------------------------
using EnsureThat;
-using Hl7.Fhir.Rest;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
-using Microsoft.Health.Common;
using Microsoft.Health.Extensions.Fhir;
using Microsoft.Health.Extensions.Fhir.Config;
+using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Config;
using Microsoft.Health.Fhir.Ingest.Service;
@@ -33,8 +32,12 @@ internal static IWebJobsBuilder AddFhirHealthCheck(this IWebJobsBuilder builder)
builder.Services.Configure(config.GetSection("FhirClient"));
// Register services
- builder.Services.TryAddSingleton, FhirClientFactory>();
- builder.Services.TryAddSingleton(sp => sp.GetRequiredService>().Create());
+ builder.Services.AddFhirClient(config);
+
+ builder.Services.TryAddSingleton();
+
+ builder.Services.TryAddSingleton();
+
builder.Services.TryAddSingleton();
builder.AddExtension();
diff --git a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Host/MeasurementFhirImportExtensions.cs b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Host/MeasurementFhirImportExtensions.cs
index 5a8b33c2..ddd76f62 100644
--- a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Host/MeasurementFhirImportExtensions.cs
+++ b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Host/MeasurementFhirImportExtensions.cs
@@ -6,16 +6,15 @@
using System;
using EnsureThat;
using Hl7.Fhir.Model;
-using Hl7.Fhir.Rest;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
-using Microsoft.Health.Common;
using Microsoft.Health.Extensions.Fhir;
using Microsoft.Health.Extensions.Fhir.Config;
+using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Config;
using Microsoft.Health.Fhir.Ingest.Service;
using Microsoft.Health.Fhir.Ingest.Template;
@@ -37,10 +36,13 @@ public static IWebJobsBuilder AddMeasurementFhirImport(this IWebJobsBuilder buil
builder.Services.Configure(config.GetSection("ResourceIdentity"));
builder.Services.Configure(config.GetSection("FhirClient"));
- builder.Services.TryAddSingleton, FhirClientFactory>();
- builder.Services.TryAddSingleton(sp => sp.GetRequiredService>().Create());
- builder.Services.TryAddSingleton, Observation>, R4FhirLookupTemplateProcessor>();
+ builder.Services.AddFhirClient(config);
+
+ builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton(ResolveResourceIdentityService);
+ builder.Services.TryAddSingleton();
+
+ builder.Services.TryAddSingleton, Observation>, R4FhirLookupTemplateProcessor>();
builder.Services.TryAddSingleton(sp => new MemoryCache(Options.Create(new MemoryCacheOptions { SizeLimit = 5000 })));
builder.Services.TryAddSingleton();
@@ -55,9 +57,9 @@ private static IResourceIdentityService ResolveResourceIdentityService(IServiceP
{
EnsureArg.IsNotNull(serviceProvider, nameof(serviceProvider));
- var fhirClient = serviceProvider.GetRequiredService();
+ var fhirService = serviceProvider.GetRequiredService();
var resourceIdentityOptions = serviceProvider.GetRequiredService>();
- return ResourceIdentityServiceFactory.Instance.Create(resourceIdentityOptions.Value, fhirClient);
+ return ResourceIdentityServiceFactory.Instance.Create(resourceIdentityOptions.Value, fhirService);
}
}
}
diff --git a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Microsoft.Health.Fhir.R4.Ingest.csproj b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Microsoft.Health.Fhir.R4.Ingest.csproj
index 82dfbf08..b871c4b5 100644
--- a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Microsoft.Health.Fhir.R4.Ingest.csproj
+++ b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Microsoft.Health.Fhir.R4.Ingest.csproj
@@ -26,15 +26,15 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientCreateIdentityService.cs b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientCreateIdentityService.cs
index 2abf6eb3..e7c8c8cc 100644
--- a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientCreateIdentityService.cs
+++ b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientCreateIdentityService.cs
@@ -6,7 +6,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using EnsureThat;
-using Hl7.Fhir.Rest;
using Microsoft.Health.Extensions.Fhir;
using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Config;
@@ -20,13 +19,13 @@ namespace Microsoft.Health.Fhir.Ingest.Service
[ResourceIdentityService(nameof(R4DeviceAndPatientCreateIdentityService))]
public class R4DeviceAndPatientCreateIdentityService : R4DeviceAndPatientLookupIdentityService
{
- public R4DeviceAndPatientCreateIdentityService(FhirClient fhirClient)
- : base(fhirClient)
+ public R4DeviceAndPatientCreateIdentityService(IFhirService fhirService)
+ : base(fhirService)
{
}
- public R4DeviceAndPatientCreateIdentityService(FhirClient fhirClient, ResourceManagementService resourceIdService)
- : base(fhirClient, resourceIdService)
+ public R4DeviceAndPatientCreateIdentityService(IFhirService fhirService, ResourceManagementService resourceIdService)
+ : base(fhirService, resourceIdService)
{
}
@@ -70,14 +69,12 @@ protected async override Task> ResolveResource
// Begin critical section
var patient = await ResourceManagementService.EnsureResourceByIdentityAsync(
- FhirClient,
input.PatientId,
null,
(p, id) => p.Identifier = new List { id })
.ConfigureAwait(false);
var device = await ResourceManagementService.EnsureResourceByIdentityAsync(
- FhirClient,
GetDeviceIdentity(input),
ResourceIdentityOptions?.DefaultDeviceIdentifierSystem,
(d, id) =>
@@ -92,7 +89,7 @@ protected async override Task> ResolveResource
if (device.Patient == null)
{
device.Patient = patient.ToReference();
- device = await FhirClient.UpdateAsync(device, true).ConfigureAwait(false);
+ device = await FhirService.UpdateResourceAsync(device).ConfigureAwait(false);
}
else if (device.Patient.GetId() != patient.Id)
{
@@ -105,4 +102,4 @@ protected async override Task> ResolveResource
return (device.Id, patient.Id);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientLookupIdentityService.cs b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientLookupIdentityService.cs
index b15a7b13..8e63fc91 100644
--- a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientLookupIdentityService.cs
+++ b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientLookupIdentityService.cs
@@ -5,7 +5,6 @@
using System.Threading.Tasks;
using EnsureThat;
-using Hl7.Fhir.Rest;
using Microsoft.Health.Extensions.Fhir;
using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Config;
@@ -19,21 +18,21 @@ namespace Microsoft.Health.Fhir.Ingest.Service
[ResourceIdentityService(nameof(R4DeviceAndPatientLookupIdentityService))]
public class R4DeviceAndPatientLookupIdentityService : DeviceAndPatientLookupIdentityService
{
- private readonly FhirClient _fhirClient;
+ private readonly IFhirService _fhirService;
private readonly ResourceManagementService _resourceManagementService;
- public R4DeviceAndPatientLookupIdentityService(FhirClient fhirClient)
- : this(fhirClient, new ResourceManagementService())
+ public R4DeviceAndPatientLookupIdentityService(IFhirService fhirService)
+ : this(fhirService, new ResourceManagementService(fhirService))
{
}
- public R4DeviceAndPatientLookupIdentityService(FhirClient fhirClient, ResourceManagementService resourceManagementService)
+ public R4DeviceAndPatientLookupIdentityService(IFhirService fhirService, ResourceManagementService resourceManagementService)
{
- _fhirClient = EnsureArg.IsNotNull(fhirClient, nameof(fhirClient));
+ _fhirService = EnsureArg.IsNotNull(fhirService, nameof(fhirService));
_resourceManagementService = EnsureArg.IsNotNull(resourceManagementService, nameof(resourceManagementService));
}
- protected FhirClient FhirClient => _fhirClient;
+ protected IFhirService FhirService => _fhirService;
protected ResourceManagementService ResourceManagementService => _resourceManagementService;
@@ -46,8 +45,8 @@ protected static string GetPatientIdFromDevice(Model.Device device)
protected async override Task<(string DeviceId, string PatientId)> LookUpDeviceAndPatientIdAsync(string value, string system = null)
{
- var device = await ResourceManagementService.GetResourceByIdentityAsync(FhirClient, value, system).ConfigureAwait(false) ?? throw new FhirResourceNotFoundException(ResourceType.Device);
+ var device = await ResourceManagementService.GetResourceByIdentityAsync(value, system).ConfigureAwait(false) ?? throw new FhirResourceNotFoundException(ResourceType.Device);
return (device.Id, GetPatientIdFromDevice(device));
}
}
-}
+}
\ No newline at end of file
diff --git a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientWithEncounterLookupIdentityService.cs b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientWithEncounterLookupIdentityService.cs
index 463df5c4..6af601c5 100644
--- a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientWithEncounterLookupIdentityService.cs
+++ b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4DeviceAndPatientWithEncounterLookupIdentityService.cs
@@ -6,7 +6,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using EnsureThat;
-using Hl7.Fhir.Rest;
using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Config;
using Microsoft.Health.Fhir.Ingest.Data;
@@ -23,13 +22,13 @@ namespace Microsoft.Health.Fhir.Ingest.Service
[ResourceIdentityService(nameof(R4DeviceAndPatientWithEncounterLookupIdentityService))]
public class R4DeviceAndPatientWithEncounterLookupIdentityService : R4DeviceAndPatientLookupIdentityService
{
- public R4DeviceAndPatientWithEncounterLookupIdentityService(FhirClient fhirClient)
- : base(fhirClient)
+ public R4DeviceAndPatientWithEncounterLookupIdentityService(IFhirService fhirService)
+ : base(fhirService)
{
}
- public R4DeviceAndPatientWithEncounterLookupIdentityService(FhirClient fhirClient, ResourceManagementService resourceIdService)
- : base(fhirClient, resourceIdService)
+ public R4DeviceAndPatientWithEncounterLookupIdentityService(IFhirService fhirService, ResourceManagementService resourceIdService)
+ : base(fhirService, resourceIdService)
{
}
@@ -44,7 +43,7 @@ protected async override Task> ResolveResource
throw new ResourceIdentityNotDefinedException(ResourceType.Encounter);
}
- var encounter = await ResourceManagementService.GetResourceByIdentityAsync(FhirClient, input.EncounterId, null).ConfigureAwait(false) ?? throw new FhirResourceNotFoundException(ResourceType.Encounter);
+ var encounter = await ResourceManagementService.GetResourceByIdentityAsync(input.EncounterId, null).ConfigureAwait(false) ?? throw new FhirResourceNotFoundException(ResourceType.Encounter);
identities[ResourceType.Encounter] = encounter?.Id;
return identities;
diff --git a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4FhirHealthService.cs b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4FhirHealthService.cs
index 3af94a11..86554810 100644
--- a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4FhirHealthService.cs
+++ b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4FhirHealthService.cs
@@ -9,6 +9,8 @@
using EnsureThat;
using Hl7.Fhir.Rest;
using Microsoft.Health.Extensions.Fhir.Search;
+using Microsoft.Health.Extensions.Fhir.Service;
+using Microsoft.Health.Fhir.Client;
using Microsoft.Health.Fhir.Ingest.Data;
namespace Microsoft.Health.Fhir.Ingest.Service
@@ -16,11 +18,11 @@ namespace Microsoft.Health.Fhir.Ingest.Service
public class R4FhirHealthService :
FhirHealthService
{
- private readonly FhirClient _client;
+ private readonly IFhirService _fhirService;
- public R4FhirHealthService(FhirClient fhirClient)
+ public R4FhirHealthService(IFhirService fhirService)
{
- _client = EnsureArg.IsNotNull(fhirClient, nameof(fhirClient));
+ _fhirService = EnsureArg.IsNotNull(fhirService, nameof(fhirService));
}
public override async Task CheckHealth(CancellationToken token = default)
@@ -30,16 +32,16 @@ public override async Task CheckHealth(CancellationToken
while (!token.IsCancellationRequested)
{
SearchParams search = new SearchParams().SetCount(1);
- Hl7.Fhir.Model.Bundle result = await _client.SearchAsync(search);
+ Hl7.Fhir.Model.Bundle result = await _fhirService.SearchForResourceAsync(Hl7.Fhir.Model.ResourceType.StructureDefinition, query: null, search.Count, token).ConfigureAwait(false);
return await Task.FromResult(new FhirHealthCheckStatus(string.Empty, 200));
}
token.ThrowIfCancellationRequested();
return await Task.FromResult(new FhirHealthCheckStatus(token.ToString(), 500));
}
- catch (FhirOperationException ex)
+ catch (FhirException ex)
{
- return await Task.FromResult(new FhirHealthCheckStatus(ex.Message, (int)ex.Status));
+ return await Task.FromResult(new FhirHealthCheckStatus(ex.Message, (int)ex.StatusCode));
}
catch (IdentityModel.Clients.ActiveDirectory.AdalServiceException ex)
{
diff --git a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4FhirImportService.cs b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4FhirImportService.cs
index f3347259..2f972c61 100644
--- a/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4FhirImportService.cs
+++ b/src/lib/Microsoft.Health.Fhir.R4.Ingest/Service/R4FhirImportService.cs
@@ -7,11 +7,12 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using EnsureThat;
-using Hl7.Fhir.Rest;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Health.Extensions.Fhir;
using Microsoft.Health.Extensions.Fhir.Search;
+using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Extensions.Fhir.Telemetry.Exceptions;
+using Microsoft.Health.Fhir.Client;
using Microsoft.Health.Fhir.Ingest.Data;
using Microsoft.Health.Fhir.Ingest.Telemetry;
using Microsoft.Health.Fhir.Ingest.Template;
@@ -24,15 +25,20 @@ namespace Microsoft.Health.Fhir.Ingest.Service
public class R4FhirImportService :
FhirImportService
{
- private readonly FhirClient _client;
+ private readonly IFhirService _fhirService;
private readonly IFhirTemplateProcessor, Model.Observation> _fhirTemplateProcessor;
private readonly IMemoryCache _observationCache;
private readonly ITelemetryLogger _logger;
- public R4FhirImportService(IResourceIdentityService resourceIdentityService, FhirClient fhirClient, IFhirTemplateProcessor, Model.Observation> fhirTemplateProcessor, IMemoryCache observationCache, ITelemetryLogger logger)
+ public R4FhirImportService(
+ IResourceIdentityService resourceIdentityService,
+ IFhirService fhirService,
+ IFhirTemplateProcessor, Model.Observation> fhirTemplateProcessor,
+ IMemoryCache observationCache,
+ ITelemetryLogger logger)
{
_fhirTemplateProcessor = EnsureArg.IsNotNull(fhirTemplateProcessor, nameof(fhirTemplateProcessor));
- _client = EnsureArg.IsNotNull(fhirClient, nameof(fhirClient));
+ _fhirService = EnsureArg.IsNotNull(fhirService, nameof(fhirService));
_observationCache = EnsureArg.IsNotNull(observationCache, nameof(observationCache));
_logger = EnsureArg.IsNotNull(logger, nameof(logger));
@@ -73,7 +79,7 @@ public virtual async Task SaveObservationAsync(ILookupTemplate
- .Handle(ex => ex.Status == System.Net.HttpStatusCode.Conflict || ex.Status == System.Net.HttpStatusCode.PreconditionFailed)
+ .Handle(ex => ex.StatusCode == System.Net.HttpStatusCode.Conflict || ex.StatusCode == System.Net.HttpStatusCode.PreconditionFailed)
.RetryAsync(2, async (polyRes, attempt) =>
{
// 409 Conflict or 412 Precondition Failed can occur if the Observation.meta.versionId does not match the update request.
@@ -101,7 +107,7 @@ public virtual async Task SaveObservationAsync(ILookupTemplate SaveObservationAsync(ILookupTemplate GetObservationFromServerAsync(Model.Identifier identifier)
{
- var searchParams = identifier.ToSearchParams();
- var result = await _client.SearchAsync(searchParams).ConfigureAwait(false);
- return await result.ReadOneFromBundleWithContinuationAsync(_client);
+ var result = await _fhirService.SearchForResourceAsync(Model.ResourceType.Observation, identifier.ToSearchQueryParameter()).ConfigureAwait(false);
+ return await result.ReadOneFromBundleWithContinuationAsync(_fhirService);
}
}
}
\ No newline at end of file
diff --git a/test/Microsoft.Health.Common.UnitTests/Microsoft.Health.Common.UnitTests.csproj b/test/Microsoft.Health.Common.UnitTests/Microsoft.Health.Common.UnitTests.csproj
index 5650e8e5..c8dab4c3 100644
--- a/test/Microsoft.Health.Common.UnitTests/Microsoft.Health.Common.UnitTests.csproj
+++ b/test/Microsoft.Health.Common.UnitTests/Microsoft.Health.Common.UnitTests.csproj
@@ -1,40 +1,42 @@
-
- net6.0
- ..\..\CustomAnalysisRules.Test.ruleset
- true
- Off
- Microsoft.Health.Common.UnitTests
- 7.3
-
-
- true
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
+
+ net6.0
+ ..\..\CustomAnalysisRules.Test.ruleset
+ true
+ Off
+ Microsoft.Health.Common.UnitTests
+ 7.3
+
+
+ true
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.Health.Common.UnitTests/Utilities.cs b/test/Microsoft.Health.Common.UnitTests/Utilities.cs
new file mode 100644
index 00000000..f598c3ad
--- /dev/null
+++ b/test/Microsoft.Health.Common.UnitTests/Utilities.cs
@@ -0,0 +1,18 @@
+// -------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
+// -------------------------------------------------------------------------------------------------
+
+using Microsoft.Health.Extensions.Fhir.Service;
+using NSubstitute;
+
+namespace Microsoft.Health.Common
+{
+ public static class Utilities
+ {
+ public static IFhirService CreateMockFhirService()
+ {
+ return Substitute.For();
+ }
+ }
+}
diff --git a/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/BundleExtensionsTests.cs b/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/BundleExtensionsTests.cs
index 76769d4a..1c79f11e 100644
--- a/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/BundleExtensionsTests.cs
+++ b/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/BundleExtensionsTests.cs
@@ -7,9 +7,10 @@
using System.Collections.Generic;
using Hl7.Fhir.Model;
using Hl7.Fhir.Serialization;
-using Microsoft.Health.Tests.Common;
+using Microsoft.Health.Common;
using NSubstitute;
using Xunit;
+using Task = System.Threading.Tasks.Task;
namespace Microsoft.Health.Extensions.Fhir.R4.UnitTests
{
@@ -26,7 +27,7 @@ public async void GivenNoEntriesAndNoContinuationToken_ReadOneFromBundleWithCont
Link = new List(),
};
- var client = Utilities.CreateMockFhirClient();
+ var client = Utilities.CreateMockFhirService();
Assert.Null(await bundle.ReadOneFromBundleWithContinuationAsync(client));
}
@@ -50,10 +51,7 @@ public async void GivenOneEntryAndNoContinuationToken_ReadOneFromBundleWithConti
};
bundle.Entry.Add(entry);
- MockFhirResourceHttpMessageHandler messageHandler = Utilities.CreateMockMessageHandler();
- messageHandler.GetReturnContent(default).ReturnsForAnyArgs((Bundle)null);
-
- var client = Utilities.CreateMockFhirClient(messageHandler);
+ var client = Utilities.CreateMockFhirService();
var result = await bundle.ReadOneFromBundleWithContinuationAsync(client);
@@ -88,9 +86,10 @@ public async void GivenOneEntryAfterContinuationToken_ReadOneFromBundleWithConti
};
continuationBundle.Entry.Add(entry);
- MockFhirResourceHttpMessageHandler messageHandler = Utilities.CreateMockMessageHandler();
- messageHandler.GetReturnContent(default).ReturnsForAnyArgs(continuationBundle, null);
- var client = Utilities.CreateMockFhirClient(messageHandler);
+ var client = Utilities.CreateMockFhirService();
+ client.IterateOverAdditionalBundlesAsync(Arg.Any()).Returns(
+ x => GetTestValues(continuationBundle),
+ x => null);
var result = await bundle.ReadOneFromBundleWithContinuationAsync(client);
@@ -121,7 +120,7 @@ public async void GivenTwoEntriesAndNoContinuationToken_ReadOneFromBundleWithCon
};
bundle.Entry.Add(entry2);
- var client = Utilities.CreateMockFhirClient();
+ var client = Utilities.CreateMockFhirService();
await Assert.ThrowsAsync>(() => bundle.ReadOneFromBundleWithContinuationAsync(client));
}
@@ -162,11 +161,19 @@ public async void GivenOneEntryBeforeAndAfterContinuationToken_ReadOneFromBundle
};
continuationBundle.Entry.Add(entry2);
- MockFhirResourceHttpMessageHandler messageHandler = Utilities.CreateMockMessageHandler();
- messageHandler.GetReturnContent(default).ReturnsForAnyArgs(continuationBundle, null);
- var client = Utilities.CreateMockFhirClient(messageHandler);
+ var client = Utilities.CreateMockFhirService();
+ client.IterateOverAdditionalBundlesAsync(Arg.Any()).Returns(
+ x => GetTestValues(continuationBundle),
+ x => null);
await Assert.ThrowsAsync>(() => bundle.ReadOneFromBundleWithContinuationAsync(client));
}
+
+ private static async IAsyncEnumerable GetTestValues(Bundle bundle)
+ {
+ yield return bundle;
+
+ await Task.CompletedTask;
+ }
}
}
diff --git a/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirServiceValidatorTests.cs b/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirClientValidatorTests.cs
similarity index 55%
rename from test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirServiceValidatorTests.cs
rename to test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirClientValidatorTests.cs
index a46e1261..16ee3aef 100644
--- a/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirServiceValidatorTests.cs
+++ b/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirClientValidatorTests.cs
@@ -3,38 +3,40 @@
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------
+using System;
+using System.Threading.Tasks;
using Hl7.Fhir.Rest;
using Microsoft.Health.Logging.Telemetry;
using NSubstitute;
using Xunit;
+using FhirClient = Microsoft.Health.Fhir.Client.FhirClient;
namespace Microsoft.Health.Extensions.Fhir.R4.UnitTests
{
- public class FhirServiceValidatorTests
+ public class FhirClientValidatorTests
{
[Theory]
[InlineData("https://testfoobar.azurehealthcareapis.com")]
[InlineData("https://microsoft.com")]
- public void GivenInvalidFhirServiceUrl_WhenValidateFhirService_ThenNotValidReturned_Test(string url)
+ public async Task GivenInvalidFhirServiceUrl_WhenValidateFhirService_ThenNotValidReturned_Test(string url)
{
- ValidateFhirServiceUrl(url, false);
+ await ValidateFhirClientUrl(url, false);
}
- private void ValidateFhirServiceUrl(string url, bool expectedIsValid)
+ private async Task ValidateFhirClientUrl(string url, bool expectedIsValid)
{
var fhirClientSettings = new FhirClientSettings
{
PreferredFormat = ResourceFormat.Json,
};
- using (var client = new FhirClient(url, fhirClientSettings))
- {
- var logger = Substitute.For();
+ var fhirClient = new FhirClient(new Uri(url), fhirClientSettings.PreferredFormat);
+
+ var logger = Substitute.For();
- bool actualIsValid = FhirServiceValidator.ValidateFhirService(client, logger);
+ bool actualIsValid = await fhirClient.ValidateFhirClientAsync(logger);
- Assert.Equal(expectedIsValid, actualIsValid);
- }
+ Assert.Equal(expectedIsValid, actualIsValid);
}
}
}
diff --git a/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirServiceExceptionProcessorTests.cs b/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirServiceExceptionProcessorTests.cs
index 4906604f..00ba4efc 100644
--- a/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirServiceExceptionProcessorTests.cs
+++ b/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/FhirServiceExceptionProcessorTests.cs
@@ -7,9 +7,10 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
-using Hl7.Fhir.Rest;
+using Hl7.Fhir.Model;
using Microsoft.Health.Common.Telemetry;
using Microsoft.Health.Extensions.Fhir.Telemetry.Exceptions;
+using Microsoft.Health.Fhir.Client;
using Microsoft.Health.Logging.Telemetry;
using Microsoft.Identity.Client;
using NSubstitute;
@@ -19,14 +20,15 @@ namespace Microsoft.Health.Extensions.Fhir.R4.UnitTests
{
public class FhirServiceExceptionProcessorTests
{
- private static readonly Exception _fhirForbiddenEx = new FhirOperationException("test", HttpStatusCode.Forbidden);
- private static readonly Exception _fhirNotFoundEx = new FhirOperationException("test", HttpStatusCode.NotFound);
- private static readonly Exception _fhirBadRequestEx = new FhirOperationException("test", HttpStatusCode.BadRequest);
+ private static readonly Exception _fhirForbiddenEx = new FhirException(new FhirResponse(new HttpResponseMessage(HttpStatusCode.Forbidden), new OperationOutcome()));
+ private static readonly Exception _fhirNotFoundEx = new FhirException(new FhirResponse(new HttpResponseMessage(HttpStatusCode.NotFound), new OperationOutcome()));
+ private static readonly Exception _fhirBadRequestEx = new FhirException(new FhirResponse(new HttpResponseMessage(HttpStatusCode.BadRequest), new OperationOutcome()));
private static readonly Exception _argEndpointNullEx = new ArgumentNullException("endpoint");
private static readonly Exception _argEndpointEx = new ArgumentException("endpoint", "Endpoint must be absolute");
private static readonly Exception _argEx = new ArgumentException("test_message", "test_param");
private static readonly Exception _uriEx = new UriFormatException();
private static readonly Exception _httpNotKnownEx = new HttpRequestException("Name or service not known");
+ private static readonly Exception _httpNotFoundEx = new HttpRequestException("test_message", new Exception(), HttpStatusCode.NotFound);
private static readonly Exception _httpEx = new HttpRequestException();
private static readonly Exception _msalInvalidResourceEx = new MsalServiceException("invalid_resource", "test_message");
private static readonly Exception _msalInvalidScopeEx = new MsalServiceException("invalid_scope", "test_message");
@@ -43,6 +45,7 @@ public class FhirServiceExceptionProcessorTests
new object[] { _argEndpointEx, "FHIRServiceErrorConfigurationError", nameof(ErrorSource.User) },
new object[] { _argEx, "FHIRServiceErrorArgumentErrortest_param" },
new object[] { _uriEx, "FHIRServiceErrorConfigurationError", nameof(ErrorSource.User) },
+ new object[] { _httpNotFoundEx, "FHIRServiceErrorHttpRequestErrorNotFound" },
new object[] { _httpNotKnownEx, "FHIRServiceErrorConfigurationError", nameof(ErrorSource.User) },
new object[] { _httpEx, "FHIRServiceErrorHttpRequestError" },
new object[] { _msalInvalidResourceEx, "FHIRServiceErrorConfigurationError", nameof(ErrorSource.User) },
@@ -56,12 +59,13 @@ public class FhirServiceExceptionProcessorTests
{
new object[] { _fhirForbiddenEx, typeof(UnauthorizedAccessFhirServiceException) },
new object[] { _fhirNotFoundEx, typeof(InvalidFhirServiceException) },
- new object[] { _fhirBadRequestEx, typeof(FhirOperationException) },
+ new object[] { _fhirBadRequestEx, typeof(FhirException) },
new object[] { _argEndpointNullEx, typeof(InvalidFhirServiceException) },
new object[] { _argEndpointEx, typeof(InvalidFhirServiceException) },
new object[] { _argEx, typeof(ArgumentException) },
new object[] { _uriEx, typeof(InvalidFhirServiceException) },
new object[] { _httpNotKnownEx, typeof(InvalidFhirServiceException) },
+ new object[] { _httpNotFoundEx, typeof(HttpRequestException) },
new object[] { _httpEx, typeof(HttpRequestException) },
new object[] { _msalInvalidResourceEx, typeof(InvalidFhirServiceException) },
new object[] { _msalInvalidScopeEx, typeof(InvalidFhirServiceException) },
diff --git a/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/Microsoft.Health.Extensions.Fhir.R4.UnitTests.csproj b/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/Microsoft.Health.Extensions.Fhir.R4.UnitTests.csproj
index 44591b7d..da62e9be 100644
--- a/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/Microsoft.Health.Extensions.Fhir.R4.UnitTests.csproj
+++ b/test/Microsoft.Health.Extensions.Fhir.R4.UnitTests/Microsoft.Health.Extensions.Fhir.R4.UnitTests.csproj
@@ -4,7 +4,7 @@
..\..\CustomAnalysisRules.Test.ruleset
true
false
- 7.3
+ 10.0
true
@@ -27,7 +27,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
@@ -35,6 +35,6 @@
-
+
diff --git a/test/Microsoft.Health.Fhir.Ingest.UnitTests/Service/EventProcessingMeterTests.cs b/test/Microsoft.Health.Fhir.Ingest.UnitTests/Service/EventProcessingMeterTests.cs
index 78b72f8c..e26eacd7 100644
--- a/test/Microsoft.Health.Fhir.Ingest.UnitTests/Service/EventProcessingMeterTests.cs
+++ b/test/Microsoft.Health.Fhir.Ingest.UnitTests/Service/EventProcessingMeterTests.cs
@@ -4,7 +4,6 @@
// -------------------------------------------------------------------------------------------------
using System;
-using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.EventHubs;
diff --git a/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Microsoft.Health.Fhir.R4.Ingest.UnitTests.csproj b/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Microsoft.Health.Fhir.R4.Ingest.UnitTests.csproj
index 275373d8..adc6e025 100644
--- a/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Microsoft.Health.Fhir.R4.Ingest.UnitTests.csproj
+++ b/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Microsoft.Health.Fhir.R4.Ingest.UnitTests.csproj
@@ -38,7 +38,7 @@
-
+
diff --git a/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientCreateIdentityServiceTests.cs b/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientCreateIdentityServiceTests.cs
index 03c1c43b..19b496db 100644
--- a/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientCreateIdentityServiceTests.cs
+++ b/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientCreateIdentityServiceTests.cs
@@ -5,11 +5,10 @@
using System;
using System.Threading.Tasks;
-using Hl7.Fhir.Rest;
+using Microsoft.Health.Common;
using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Config;
using Microsoft.Health.Fhir.Ingest.Data;
-using Microsoft.Health.Tests.Common;
using NSubstitute;
using Xunit;
using Model = Hl7.Fhir.Model;
@@ -21,8 +20,8 @@ public class R4DeviceAndPatientCreateIdentityServiceTests
[Fact]
public async void GivenValidDeviceIdentifier_WhenResolveResourceIdentitiesAsync_ThenDeviceAndPatientIdReturnedAndCreateNotInvoked_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
Id = "1",
@@ -32,7 +31,7 @@ public async void GivenValidDeviceIdentifier_WhenResolveResourceIdentitiesAsync_
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
using (var idSrv = new R4DeviceAndPatientCreateIdentityService(fhirClient, resourceService))
@@ -43,16 +42,16 @@ public async void GivenValidDeviceIdentifier_WhenResolveResourceIdentitiesAsync_
Assert.Equal("123", ids[ResourceType.Patient]);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
- await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null, null);
- await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null, null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
+ await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null);
+ await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null);
}
[Fact]
public async void GivenValidDeviceIdentifierWithSystem_WhenResolveResourceIdentitiesAsync_ThenDeviceAndPatientIdReturnedAndCreateNotInvokedWithSystemUsed_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
Id = "1",
@@ -62,7 +61,7 @@ public async void GivenValidDeviceIdentifierWithSystem_WhenResolveResourceIdenti
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
using (var idSrv = new R4DeviceAndPatientCreateIdentityService(fhirClient, resourceService))
@@ -74,16 +73,16 @@ public async void GivenValidDeviceIdentifierWithSystem_WhenResolveResourceIdenti
Assert.Equal("123", ids[ResourceType.Patient]);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", "mySystem");
- await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null, null);
- await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null, null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", "mySystem");
+ await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null);
+ await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null);
}
[Fact]
public async void GivenPatientNotFoundException_WhenResolveResourceIdentitiesAsync_ThenDeviceAndPatientCreateInvokedAndIdsReturned_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
@@ -96,14 +95,14 @@ public async void GivenPatientNotFoundException_WhenResolveResourceIdentitiesAsy
Id = "123",
};
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
mg.PatientId.Returns("patientId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromException(new FhirResourceNotFoundException(ResourceType.Patient)));
using (var idSrv = new R4DeviceAndPatientCreateIdentityService(fhirClient, resourceService))
@@ -114,16 +113,16 @@ public async void GivenPatientNotFoundException_WhenResolveResourceIdentitiesAsy
Assert.Equal("123", ids[ResourceType.Patient]);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
- await resourceService.Received(1).EnsureResourceByIdentityAsync(fhirClient, "deviceId", null, Arg.Any>());
- await resourceService.Received(1).EnsureResourceByIdentityAsync(fhirClient, "patientId", null, Arg.Any>());
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
+ await resourceService.Received(1).EnsureResourceByIdentityAsync("deviceId", null, Arg.Any>());
+ await resourceService.Received(1).EnsureResourceByIdentityAsync("patientId", null, Arg.Any>());
}
[Fact]
public async void GivenDeviceNotFoundException_WhenResolveResourceIdentitiesAsync_ThenDeviceAndPatientCreateInvokedAndIdsReturned_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
@@ -136,14 +135,14 @@ public async void GivenDeviceNotFoundException_WhenResolveResourceIdentitiesAsyn
Id = "123",
};
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
mg.PatientId.Returns("patientId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromException(new FhirResourceNotFoundException(ResourceType.Device)));
using (var idSrv = new R4DeviceAndPatientCreateIdentityService(fhirClient, resourceService))
@@ -154,16 +153,16 @@ public async void GivenDeviceNotFoundException_WhenResolveResourceIdentitiesAsyn
Assert.Equal("123", ids[ResourceType.Patient]);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
- await resourceService.Received(1).EnsureResourceByIdentityAsync(fhirClient, "deviceId", null, Arg.Any>());
- await resourceService.Received(1).EnsureResourceByIdentityAsync(fhirClient, "patientId", null, Arg.Any>());
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
+ await resourceService.Received(1).EnsureResourceByIdentityAsync("deviceId", null, Arg.Any>());
+ await resourceService.Received(1).EnsureResourceByIdentityAsync("patientId", null, Arg.Any>());
}
[Fact]
public async void GivenDeviceNotFoundExceptionWithDeviceSystemSet_WhenResolveResourceIdentitiesAsync_ThenDeviceAndPatientCreateInvokedWithDeviceSystemAndIdsReturned_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
@@ -176,14 +175,14 @@ public async void GivenDeviceNotFoundExceptionWithDeviceSystemSet_WhenResolveRes
Id = "123",
};
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
mg.PatientId.Returns("patientId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromException(new FhirResourceNotFoundException(ResourceType.Device)));
using (var idSrv = new R4DeviceAndPatientCreateIdentityService(fhirClient, resourceService))
@@ -195,9 +194,9 @@ public async void GivenDeviceNotFoundExceptionWithDeviceSystemSet_WhenResolveRes
Assert.Equal("123", ids[ResourceType.Patient]);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", "mySystem");
- await resourceService.Received(1).EnsureResourceByIdentityAsync(fhirClient, "deviceId", "mySystem", Arg.Any>());
- await resourceService.Received(1).EnsureResourceByIdentityAsync(fhirClient, "patientId", null, Arg.Any>());
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", "mySystem");
+ await resourceService.Received(1).EnsureResourceByIdentityAsync("deviceId", "mySystem", Arg.Any>());
+ await resourceService.Received(1).EnsureResourceByIdentityAsync("patientId", null, Arg.Any>());
}
[Theory]
@@ -206,8 +205,8 @@ public async void GivenDeviceNotFoundExceptionWithDeviceSystemSet_WhenResolveRes
[InlineData(" ")]
public async void GivenIdNotFoundExceptionWithNoPatientId_WhenResolveResourceIdentitiesAsync_ThenResourceIdentityNotDefinedExceptionThrown_Test(string value)
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
@@ -220,15 +219,15 @@ public async void GivenIdNotFoundExceptionWithNoPatientId_WhenResolveResourceIde
Id = "123",
};
- var createService = Substitute.For();
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
+ var createService = Substitute.For(fhirClient);
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
mg.PatientId.Returns(value);
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromException(new FhirResourceNotFoundException(ResourceType.Patient)));
using (var idSrv = new R4DeviceAndPatientCreateIdentityService(fhirClient, resourceService))
@@ -237,16 +236,16 @@ public async void GivenIdNotFoundExceptionWithNoPatientId_WhenResolveResourceIde
Assert.Equal(ResourceType.Patient, ex.FhirResourceType);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
- await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null, null);
- await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null, null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
+ await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null);
+ await resourceService.DidNotReceiveWithAnyArgs().EnsureResourceByIdentityAsync(null, null, null);
}
[Fact]
public async void GivenMismatchedDeviceAndPatientIdReference_WhenResolveResourceIdentitiesAsync_ThenPatientDeviceMismatchExceptionThrown_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
@@ -259,14 +258,14 @@ public async void GivenMismatchedDeviceAndPatientIdReference_WhenResolveResource
Id = "123",
};
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
- resourceService.EnsureResourceByIdentityAsync(null, null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(device));
+ resourceService.EnsureResourceByIdentityAsync(null, null, null).ReturnsForAnyArgs(Task.FromResult(patient));
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
mg.PatientId.Returns("patientId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromException(new FhirResourceNotFoundException(ResourceType.Patient)));
using (var idSrv = new R4DeviceAndPatientCreateIdentityService(fhirClient, resourceService))
@@ -274,9 +273,9 @@ public async void GivenMismatchedDeviceAndPatientIdReference_WhenResolveResource
await Assert.ThrowsAsync(() => idSrv.ResolveResourceIdentitiesAsync(mg));
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
- await resourceService.Received(1).EnsureResourceByIdentityAsync(fhirClient, "deviceId", null, Arg.Any>());
- await resourceService.Received(1).EnsureResourceByIdentityAsync(fhirClient, "patientId", null, Arg.Any>());
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
+ await resourceService.Received(1).EnsureResourceByIdentityAsync("deviceId", null, Arg.Any>());
+ await resourceService.Received(1).EnsureResourceByIdentityAsync("patientId", null, Arg.Any>());
}
}
}
diff --git a/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientLookupIdentityServiceTests.cs b/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientLookupIdentityServiceTests.cs
index 05a48e5b..2b35bf04 100644
--- a/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientLookupIdentityServiceTests.cs
+++ b/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientLookupIdentityServiceTests.cs
@@ -4,11 +4,10 @@
// -------------------------------------------------------------------------------------------------
using System.Threading.Tasks;
-using Hl7.Fhir.Rest;
+using Microsoft.Health.Common;
using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Config;
using Microsoft.Health.Fhir.Ingest.Data;
-using Microsoft.Health.Tests.Common;
using NSubstitute;
using Xunit;
using Model = Hl7.Fhir.Model;
@@ -20,8 +19,8 @@ public class R4DeviceAndPatientLookupIdentityServiceTests
[Fact]
public async void GivenValidDeviceIdentifier_WhenResolveResourceIdentitiesAsync_ThenDeviceAndPatientIdReturned_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
Id = "1",
@@ -31,7 +30,7 @@ public async void GivenValidDeviceIdentifier_WhenResolveResourceIdentitiesAsync_
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
using (var idSrv = new R4DeviceAndPatientLookupIdentityService(fhirClient, resourceService))
@@ -42,14 +41,14 @@ public async void GivenValidDeviceIdentifier_WhenResolveResourceIdentitiesAsync_
Assert.Equal("123", ids[ResourceType.Patient]);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
}
[Fact]
public async void GivenValidDeviceIdentifierWhenDefaultSystemSet_WhenResolveResourceIdentitiesAsync_ThenDeviceAndPatientIdReturned_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
Id = "1",
@@ -64,7 +63,7 @@ public async void GivenValidDeviceIdentifierWhenDefaultSystemSet_WhenResolveReso
DefaultDeviceIdentifierSystem = "mySystem",
};
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
using (var idSrv = new R4DeviceAndPatientLookupIdentityService(fhirClient, resourceService))
@@ -76,20 +75,20 @@ public async void GivenValidDeviceIdentifierWhenDefaultSystemSet_WhenResolveReso
Assert.Equal("123", ids[ResourceType.Patient]);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", "mySystem");
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", "mySystem");
}
[Fact]
public async void GivenDeviceWithNotPatientReference_WhenResolveResourceIdentitiesAsync_ThenFhirResourceNotFoundExceptionThrown_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
Model.Device device = new Model.Device();
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
using (var idSrv = new R4DeviceAndPatientLookupIdentityService(fhirClient, resourceService))
@@ -98,14 +97,14 @@ public async void GivenDeviceWithNotPatientReference_WhenResolveResourceIdentiti
Assert.Equal(ResourceType.Patient, ex.FhirResourceType);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
}
[Fact]
public async void GivenDeviceWithPatientReferenceUnsupportedCharacters_WhenResolveResourceIdentitiesAsync_ThenNotSupportedExceptionThrown_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
Id = "1",
@@ -115,7 +114,7 @@ public async void GivenDeviceWithPatientReferenceUnsupportedCharacters_WhenResol
var mg = Substitute.For();
mg.DeviceId.Returns("deviceId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
using (var idSrv = new R4DeviceAndPatientLookupIdentityService(fhirClient, resourceService))
@@ -124,7 +123,7 @@ public async void GivenDeviceWithPatientReferenceUnsupportedCharacters_WhenResol
Assert.Equal(ResourceType.Patient, ex.FhirResourceType);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
}
}
}
diff --git a/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientWithEncounterLookupIdentityServiceTests.cs b/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientWithEncounterLookupIdentityServiceTests.cs
index 6f1dc879..46b8e00e 100644
--- a/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientWithEncounterLookupIdentityServiceTests.cs
+++ b/test/Microsoft.Health.Fhir.R4.Ingest.UnitTests/Service/R4DeviceAndPatientWithEncounterLookupIdentityServiceTests.cs
@@ -4,10 +4,9 @@
// -------------------------------------------------------------------------------------------------
using System.Threading.Tasks;
-using Hl7.Fhir.Rest;
+using Microsoft.Health.Common;
using Microsoft.Health.Extensions.Fhir.Service;
using Microsoft.Health.Fhir.Ingest.Data;
-using Microsoft.Health.Tests.Common;
using NSubstitute;
using Xunit;
using Model = Hl7.Fhir.Model;
@@ -19,8 +18,8 @@ public class R4DeviceAndPatientWithEncounterLookupIdentityServiceTests
[Fact]
public async void GivenValidEncounterIdentifier_WhenResolveResourceIdentitiesAsync_ThenEncounterIdReturned_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
Id = "1",
@@ -36,10 +35,10 @@ public async void GivenValidEncounterIdentifier_WhenResolveResourceIdentitiesAsy
mg.DeviceId.Returns("deviceId");
mg.EncounterId.Returns("eId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(encounter));
using (var idSrv = new R4DeviceAndPatientWithEncounterLookupIdentityService(fhirClient, resourceService))
@@ -51,15 +50,15 @@ public async void GivenValidEncounterIdentifier_WhenResolveResourceIdentitiesAsy
Assert.Equal("abc", ids[ResourceType.Encounter]);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "eId", null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("eId", null);
}
[Fact]
public async void GivenInValidEncounterIdentifier_WhenResolveResourceIdentitiesAsync_ThenFhirResourceNotFoundExceptionThrown_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
Id = "1",
@@ -70,10 +69,10 @@ public async void GivenInValidEncounterIdentifier_WhenResolveResourceIdentitiesA
mg.DeviceId.Returns("deviceId");
mg.EncounterId.Returns("eId");
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult((Model.Encounter)null));
using (var idSrv = new R4DeviceAndPatientWithEncounterLookupIdentityService(fhirClient, resourceService))
@@ -82,15 +81,15 @@ public async void GivenInValidEncounterIdentifier_WhenResolveResourceIdentitiesA
Assert.Equal(ResourceType.Encounter, ex.FhirResourceType);
}
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "deviceId", null);
- await resourceService.Received(1).GetResourceByIdentityAsync(fhirClient, "eId", null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("deviceId", null);
+ await resourceService.Received(1).GetResourceByIdentityAsync("eId", null);
}
[Fact]
public async void GivenNoEncounterIdentifier_WhenResolveResourceIdentitiesAsync_ThenResourceIdentityNotDefinedExceptionThrown_Test()
{
- var fhirClient = Utilities.CreateMockFhirClient();
- var resourceService = Substitute.For();
+ var fhirClient = Utilities.CreateMockFhirService();
+ var resourceService = Substitute.For(fhirClient);
var device = new Model.Device
{
Id = "1",
@@ -101,7 +100,7 @@ public async void GivenNoEncounterIdentifier_WhenResolveResourceIdentitiesAsync_
mg.DeviceId.Returns("deviceId");
mg.EncounterId.Returns((string)null);
- resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ resourceService.GetResourceByIdentityAsync(Arg.Any(), Arg.Any())
.Returns(Task.FromResult(device));
using (var idSrv = new R4DeviceAndPatientWithEncounterLookupIdentityService(fhirClient, resourceService))
@@ -110,8 +109,8 @@ public async void GivenNoEncounterIdentifier_WhenResolveResourceIdentitiesAsync_
Assert.Equal(ResourceType.Encounter, ex.FhirResourceType);
}
- await resourceService.Received(1).GetResourceByIdentityAsync