Skip to content

Commit

Permalink
feature: add function to resolve based on FHIR version
Browse files Browse the repository at this point in the history
  • Loading branch information
mmsmits committed Mar 13, 2024
1 parent 73d355d commit adb034c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 12 deletions.
17 changes: 16 additions & 1 deletion Firely.Fhir.Packages.Tests/FhirPackageSourceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ namespace Firely.Fhir.Packages.Tests
{

[TestClass]
public class CommonFhirPackageSourceTests
public class FhirPackageSourceTests
{
private const string PACKAGESERVER = "http://packages.simplifier.net";
private const string PACKAGENAME = "TestData/testPackage.tgz";
private const string US_CORE_PACKAGE = "hl7.fhir.us.core@4.1.0";
private const string FHIR_CORE_R3 = "hl7.fhir.r3.core@3.0.2";
private const string FHIR_CORE_R4 = "hl7.fhir.r4.core@4.0.1";

//ModelInspector is needed for _resolver, but doesn't do anything in this case, since common doesn't have access to STU3 type information.
private readonly FhirPackageSource _resolver = new(new ModelInspector(FhirRelease.STU3), PACKAGENAME);
Expand Down Expand Up @@ -158,5 +160,18 @@ public async Task TestFhirCorePackages(FhirRelease release, string version, stri
toolingextension.Should().Contain("\"url\":\"http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-date-format\"");
}
}

[TestMethod]
public async Task TestGetCanonicalOfCorrectFhirVersion()
{

var R4MultiPackageSource = new FhirPackageSource(new ModelInspector(FhirRelease.R4), PACKAGESERVER, new string[] { FHIR_CORE_R3, FHIR_CORE_R4 });
var R4Pat = await R4MultiPackageSource.ResolveByCanonicalUriAsyncAsString("http://hl7.org/fhir/StructureDefinition/Patient");
R4Pat.Should().Contain($"\"fhirVersion\":\"4.0.1\"");

var STU3MultiPackageSource = new FhirPackageSource(new ModelInspector(FhirRelease.STU3), PACKAGESERVER, new string[] { FHIR_CORE_R3, FHIR_CORE_R4 });
var STU3Pat = await STU3MultiPackageSource.ResolveByCanonicalUriAsyncAsString("http://hl7.org/fhir/StructureDefinition/Patient");
STU3Pat.Should().Contain($"\"fhirVersion\":\"3.0.2\"");
}
}
}
29 changes: 24 additions & 5 deletions Firely.Fhir.Packages/Core/FileIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#nullable enable

using Hl7.Fhir.Model;
using Hl7.Fhir.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -28,26 +30,43 @@ public FileIndex()
/// </summary>
/// <param name="canonical">canonical URI used to identify the artifact</param>
/// <param name="version">version of the artifact</param>
/// <param name="fhirVersion">Only resolve files that conform to this FHIR version</param>
/// <returns>First file found with a specific canonical URI and optional version</returns>
public PackageFileReference? ResolveCanonical(string canonical, string? version = null)
public PackageFileReference? ResolveCanonical(string canonical, string? version = null, FHIRVersion? fhirVersion = null)
{
return !string.IsNullOrEmpty(version)
? this.FirstOrDefault(r => r.Canonical == canonical && r.Version == version)
: this.FirstOrDefault(r => r.Canonical == canonical);
var candidates = !string.IsNullOrEmpty(version)
? this.Where(r => r.Canonical == canonical && r.Version == version)
: this.Where(r => r.Canonical == canonical);

if (fhirVersion.GetLiteral() is { } fhirVersionString)
{
return candidates.Where(r => r.FhirVersion == fhirVersionString).FirstOrDefault();
}
else
{
return candidates.FirstOrDefault();
}
}

/// <summary>
/// Returns the best candidate found with a specific canonical URI and optional version.
/// </summary>
/// <param name="canonical">canonical URI used to identify the artifact</param>
/// <param name="version">version of the artifact</param>
/// <param name="fhirVersion">Only resolve files that conform to this FHIR version</param>
/// <returns>Returns the best candidate found with a specific canonical URI and optional version.</returns>
public PackageFileReference? ResolveBestCandidateByCanonical(string canonical, string? version = null)
public PackageFileReference? ResolveBestCandidateByCanonical(string canonical, string? version = null, FHIRVersion? fhirVersion = null)
{
var candidates = !string.IsNullOrEmpty(version)
? this.Where(r => r.Canonical == canonical && r.Version == version)
: this.Where(r => r.Canonical == canonical);


if (fhirVersion.GetLiteral() is { } fhirVersionString)
{
candidates = candidates.Where(r => r.FhirVersion == fhirVersionString);
}

return candidates.Count() > 1 ? resolveFromMultipleCandidates(candidates) : candidates.SingleOrDefault();
}

Expand Down
8 changes: 5 additions & 3 deletions Firely.Fhir.Packages/Extensions/PackageContextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#nullable enable

using Hl7.Fhir.Model;
using Hl7.Fhir.Utility;
using System;
using System.Collections.Generic;
Expand All @@ -26,12 +27,13 @@ public static class PackageContextExtensions
/// <param name="uri">Canonical uri of the resource</param>
/// <param name="version">Version of the conformance resource</param>
/// <param name="resolveBestCandidate">If there are multiple candidates, try to resolve the best instead of the first</param>
/// <param name="fhirVersion">Only resolve files that conform to this FHIR version</param>
/// <returns>File content of the conformance resource</returns>
public static async Task<string?> GetFileContentByCanonical(this PackageContext scope, string uri, string? version = null, bool resolveBestCandidate = false)
public static async Task<string?> GetFileContentByCanonical(this PackageContext scope, string uri, string? version = null, bool resolveBestCandidate = false, FHIRVersion? fhirVersion = null)
{
var reference = resolveBestCandidate
? scope.GetIndex().ResolveBestCandidateByCanonical(uri, version)
: scope.GetIndex().ResolveCanonical(uri, version);
? scope.GetIndex().ResolveBestCandidateByCanonical(uri, version, fhirVersion)
: scope.GetIndex().ResolveCanonical(uri, version, fhirVersion);

return reference is not null ? await scope.GetFileContent(reference).ConfigureAwait(false) : null;
}
Expand Down
5 changes: 2 additions & 3 deletions Firely.Fhir.Packages/Source/FhirPackageSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ private static async Task installPackageFromPath(PackageContext scope, string pa
internal async Task<string?> ResolveByCanonicalUriAsyncAsString(string uri)
{
(var url, var version) = splitCanonical(uri);
return await _context.Value.GetFileContentByCanonical(url, version, resolveBestCandidate: true).ConfigureAwait(false);
var fhirVersion = EnumUtility.ParseLiteral<FHIRVersion>(FhirReleaseParser.FhirVersionFromRelease(_provider.FhirRelease));
return await _context.Value.GetFileContentByCanonical(url, version, resolveBestCandidate: true, fhirVersion).ConfigureAwait(false);
}


private static (string url, string version) splitCanonical(string canonical)
{
if (canonical.EndsWith("|"))
Expand All @@ -224,7 +224,6 @@ private static (string url, string version) splitCanonical(string canonical)
: (canonical.Substring(0, position), canonical.Substring(position + 1));
}


///<inheritdoc/>
public async Task<Resource?> ResolveByUriAsync(string uri)
{
Expand Down

0 comments on commit adb034c

Please sign in to comment.