Skip to content

Commit

Permalink
fix: race condition caused by non-thread-safe FhirClient
Browse files Browse the repository at this point in the history
  • Loading branch information
chgl committed Nov 23, 2023
1 parent fd43e19 commit 447b770
Showing 1 changed file with 21 additions and 26 deletions.
47 changes: 21 additions & 26 deletions src/FhirPseudonymizer/Pseudonymization/GPas/GPasFhirClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Text;
using FhirPseudonymizer.Config;
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
Expand Down Expand Up @@ -36,13 +35,7 @@ IMemoryCache originalValueCache
{
this.logger = logger;

Client = clientFactory.CreateClient("gPAS");

FhirClient = new FhirClient(
Client.BaseAddress,
Client,
settings: new() { PreferredFormat = ResourceFormat.Json }
);
HttpClient = clientFactory.CreateClient("gPAS");

PseudonymCache = pseudonymCache;
OriginalValueCache = originalValueCache;
Expand Down Expand Up @@ -77,14 +70,13 @@ IMemoryCache originalValueCache

private IMemoryCache PseudonymCache { get; }
private IMemoryCache OriginalValueCache { get; }
private HttpClient Client { get; }
private HttpClient HttpClient { get; }
private FhirJsonParser FhirParser { get; } = new();
private FhirJsonSerializer FhirSerializer { get; } = new();
private TimeSpan SlidingExpiration { get; }
private TimeSpan AbsoluteExpiration { get; }
private Func<string, string, Task<string>> GetOrCreatePseudonymForResolver { get; }
private Func<string, string, Task<string>> GetOriginalValueForResolver { get; }
private FhirClient FhirClient { get; }

public async Task<string> GetOrCreatePseudonymFor(
string value,
Expand Down Expand Up @@ -154,7 +146,7 @@ private async Task<string> GetOriginalValueForV1(string pseudonym, string domain
["pseudonym"] = pseudonym
};

var response = await Client.GetAsync(
var response = await HttpClient.GetAsync(
QueryHelpers.AddQueryString("$de-pseudonymize", query)
);
response.EnsureSuccessStatusCode();
Expand All @@ -178,7 +170,7 @@ private async Task<string> GetOriginalValueForV2(string pseudonym, string domain
var responseParameters = await RequestGetOriginalValueForV2(
pseudonym,
domain,
"$de-pseudonymize"
"de-pseudonymize"
);

var pseudonymResultSet = responseParameters.Get("pseudonym-result-set").First();
Expand All @@ -202,7 +194,7 @@ private async Task<string> GetOriginalValueForV2x(string pseudonym, string domai
var responseParameters = await RequestGetOriginalValueForV2(
pseudonym,
domain,
"$dePseudonymize"
"dePseudonymize"
);

var firstResponseParameter = responseParameters.Parameter.FirstOrDefault();
Expand All @@ -229,7 +221,7 @@ private async Task<string> GetOrCreatePseudonymForV1(string value, string domain
// this currently uses a HttpClient instead of the FhirClient to leverage
// Polly, tracing, and metrics support. Once FhirClient allows for overriding the HttpClient,
// we can simplify this code a lot: https://github.com/FirelyTeam/firely-net-sdk/issues/1483
var response = await Client.GetAsync(
var response = await HttpClient.GetAsync(
QueryHelpers.AddQueryString("$pseudonymize-allow-create", query)
);
response.EnsureSuccessStatusCode();
Expand Down Expand Up @@ -280,11 +272,17 @@ private async Task<Parameters> RequestGetOrCreatePseudonymForV2(
string operation
)
{
using var fhirClient = new FhirClient(
HttpClient.BaseAddress,
HttpClient,
settings: new() { PreferredFormat = ResourceFormat.Json }
);

var parameters = new Parameters()
.Add("target", new FhirString(domain))
.Add("original", new FhirString(value));

var response = await FhirClient.WholeSystemOperationAsync(operation, parameters);
var response = await fhirClient.WholeSystemOperationAsync(operation, parameters);

return response as Parameters;
}
Expand All @@ -295,21 +293,18 @@ private async Task<Parameters> RequestGetOriginalValueForV2(
string operation
)
{
using var fhirClient = new FhirClient(
HttpClient.BaseAddress,
HttpClient,
settings: new() { PreferredFormat = ResourceFormat.Json }
);

var parameters = new Parameters()
.Add("target", new FhirString(domain))
.Add("pseudonym", new FhirString(pseudonym));

var parametersBody = await FhirSerializer.SerializeToStringAsync(parameters);
using var content = new StringContent(
parametersBody,
Encoding.UTF8,
"application/fhir+json"
);

var response = await Client.PostAsync(operation, content);
response.EnsureSuccessStatusCode();
var response = await fhirClient.WholeSystemOperationAsync(operation, parameters);

var responseContent = await response.Content.ReadAsStringAsync();
return FhirParser.Parse<Parameters>(responseContent);
return response as Parameters;
}
}

0 comments on commit 447b770

Please sign in to comment.