Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STU3: Backport changes on r4 branch to stu3 branch #859

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a2af484
Engine: Add a generic version of FhirResponse
kennethmyhra Feb 3, 2025
71921e4
Engine: Convert fields StatusCode, Key, and Resource to properties
kennethmyhra Feb 3, 2025
3facde9
Engine: Add generic versions of {,I}FhirResponseFactory.GetFhirResponse
kennethmyhra Feb 3, 2025
15357eb
Engine: Add generic method {,I}FhirService{,Base}.ReadAsync<T>()
kennethmyhra Feb 3, 2025
d14eb93
Engine: Add generic method {,I}FhirService{,Base}.VesionReadAsync<T>()
kennethmyhra Feb 3, 2025
ae38434
Documentation: Start the document MigrateFromv2Tov3
kennethmyhra Feb 3, 2025
7641041
Engine: Remove obsolete extension method AddFhirFormatters()
kennethmyhra Feb 3, 2025
a1facba
Engine: Remove obsolete ctor ResourceJsonInputFormatter()
kennethmyhra Feb 3, 2025
555fdf9
Engine: Remove obsolete ctor ResourceXmlInputFormatter()
kennethmyhra Feb 3, 2025
0a4ea18
Engine: Remove obsolete extension method ToHttpResponseMessage()
kennethmyhra Feb 3, 2025
b3e6a66
Engine: Remove unused extension method ToHttpResponseMessage()
kennethmyhra Feb 3, 2025
3211eea
Engine: Remove unused internal Func pascalToCamelCase
kennethmyhra Feb 3, 2025
6bb6bb7
Engine: Remove obsolete ctor FhirService()
kennethmyhra Feb 3, 2025
521c594
Mongo: Remove obsolete modifier constants
kennethmyhra Feb 3, 2025
8d2286b
Mongo: Alphabetize modifier constants
kennethmyhra Feb 3, 2025
94bd910
Mongo: Remove a bunch of unused constants
kennethmyhra Feb 3, 2025
59cb6f5
Mongo: Rename MONGOINDEXCOLLECTION to SEARCH_INDEX_COLLECTION
kennethmyhra Feb 3, 2025
d07fea9
Mongo: Remove no longer existing search fields
kennethmyhra Feb 3, 2025
0b63510
Mongo: Alphabetize InternalField constants
kennethmyhra Feb 3, 2025
6afe3a4
Mongo: Remove unused InternalField constants
kennethmyhra Feb 3, 2025
2f8ae31
Mongo: Properly name and captitalize InternalField constants
kennethmyhra Feb 3, 2025
abcea98
Mongo: Make InternalField class and constants internal
kennethmyhra Feb 3, 2025
575e112
Mongo: Make InternalField.ALL static readonly
kennethmyhra Feb 3, 2025
79e6e8b
Mongo: Remove unused method DetermineUniversalArgument()
kennethmyhra Feb 3, 2025
de38af0
Mongo: Remove unused methods in class Definition and Definitions
kennethmyhra Feb 3, 2025
3484a76
Engine: Remove obsolete SnapshotExtensions and corresponding methods
kennethmyhra Feb 3, 2025
68acee9
Revert github: Make dependabot ignore major versions for NuGet packages
kennethmyhra Feb 4, 2025
353db21
build(deps): bump Microsoft.AspNetCore.Identity.UI from 8.0.12 to 9.0.1
dependabot[bot] Feb 4, 2025
0ec69c7
build(deps): bump xunit.runner.visualstudio from 2.8.2 to 3.0.1
dependabot[bot] Feb 4, 2025
da2d758
build(deps): bump Microsoft.Extensions.DependencyInjection.Abstractions
dependabot[bot] Feb 4, 2025
20cad25
build(deps): bump Swashbuckle.AspNetCore from 6.9.0 to 7.2.0
dependabot[bot] Feb 4, 2025
84436ef
build(deps): bump Microsoft.EntityFrameworkCore.Sqlite
dependabot[bot] Feb 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ updates:
directory: "/"
schedule:
interval: daily
ignore:
- dependency-name: "*"
update-types: [ "version-update:semver-major" ]
- package-ecosystem: github-actions
directory: "/"
schedule:
Expand Down
19 changes: 19 additions & 0 deletions Documentation/MigrateFromv2Tov3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Migrate from 2.0 to 3.0

### Target Frameworks
We now target `netstandard2.1` and `net472`, allowing Spark to run on .NET 8.0 and later, as well as .NET Framework
4.7.2 and later.

### New classes and interfaces
- `FhirResponse&lt;T&gt;` wraps a `FhirResponse`, with the generic parameter representing the FHIR resource type.

### IFhirService, FhirServiceBase and FhirService changes
- New generic methods:
- `Task<FhirResponse<T>> ReadAsync<T>(IKey, ConditionalHeaderParameters) where T : Resource`
- `Task<FhirResponse<T>> VersionReadAsync<T>(IKey, ConditionalHeaderParameters) where T : Resource`

### IFhirResponseFactory and FhirResponseFactory changes
- New generic methods:
- `FhirResponse<T> GetFhirResponse<T>(Entry entry, IKey key = null, IEnumerable<object> parameters = null) where T : Resource`
- `FhirResponse<T> GetFhirResponse<T>(Entry entry, IKey key = null, params object[] parameters) where T : Resource`

1 change: 1 addition & 0 deletions Spark.sln
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentat
Documentation\RunningSparkInDocker.md = Documentation\RunningSparkInDocker.md
Documentation\UsingSpark.md = Documentation\UsingSpark.md
Documentation\MigrateFromv1Tov2.md = Documentation\MigrateFromv1Tov2.md
Documentation\MigrateFromv2Tov3.md = Documentation\MigrateFromv2Tov3.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{977F2FE5-C232-4F93-AA0A-73DB85A20879}"
Expand Down
2 changes: 1 addition & 1 deletion src/Spark.Engine.Test/Spark.Engine.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageReference Include="MSTest.TestFramework" Version="3.7.3" />
<PackageReference Include="NuGet.Versioning" Version="6.12.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
54 changes: 49 additions & 5 deletions src/Spark.Engine/Core/Response.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
/*
* Copyright (c) 2015-2018, Firely <[email protected]>
* Copyright (c) 2021-2025, Incendi <[email protected]>
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand All @@ -14,11 +14,55 @@ namespace Spark.Engine.Core;
// without having to implement functionality twice.
// The FhirService always responds with a "Response"

public class FhirResponse<T> where T : Resource
{
public HttpStatusCode StatusCode { get; }
public IKey Key { get; }
public T Resource { get; }

public FhirResponse(HttpStatusCode code, IKey key, T resource)
{
StatusCode = code;
Key = key;
Resource = resource;
}

public FhirResponse(HttpStatusCode code, T resource)
{
StatusCode = code;
Key = null;
Resource = resource;
}

public FhirResponse(HttpStatusCode code)
{
StatusCode = code;
}

public bool IsValid
{
get
{
int code = (int)StatusCode;
return code <= 300;
}
}

public bool HasBody => Resource != null;

public override string ToString()
{
string details = Resource != null ? string.Format("({0})", Resource.TypeName) : null;
string location = Key?.ToString();
return string.Format("{0}: {1} {2} ({3})", (int)StatusCode, StatusCode.ToString(), details, location);
}
}

public class FhirResponse
{
public HttpStatusCode StatusCode;
public IKey Key;
public Resource Resource;
public HttpStatusCode StatusCode { get; }
public IKey Key { get; }
public Resource Resource { get; internal set; }

public FhirResponse(HttpStatusCode code, IKey key, Resource resource)
{
Expand Down
14 changes: 0 additions & 14 deletions src/Spark.Engine/Core/Snapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,3 @@ public bool InRange(int index)
return (index > 0 || index <= last);
}
}

public static class SnapshotExtensions
{
[Obsolete("Method will be removed in a future version")]
public static IEnumerable<string> Keys(this Bundle bundle)
{
return bundle.GetResources().Keys();
}

public static IEnumerable<string> Keys(this IEnumerable<Resource> resources)
{
return resources.Select(e => e.VersionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -229,24 +229,6 @@ public static IMvcCoreBuilder AddFhirFormatters(this IServiceCollection services
});
}

[Obsolete("This method is obsolete and will be removed in a future version.")]
public static IMvcCoreBuilder AddFhirFormatters(this IServiceCollection services, Action<MvcOptions> setupAction = null)
{
return services.AddMvcCore(options =>
{
options.InputFormatters.Add(new ResourceJsonInputFormatter());
options.InputFormatters.Add(new ResourceXmlInputFormatter());
options.InputFormatters.Add(new BinaryInputFormatter());
options.OutputFormatters.Add(new ResourceJsonOutputFormatter());
options.OutputFormatters.Add(new ResourceXmlOutputFormatter());
options.OutputFormatters.Add(new BinaryOutputFormatter());

options.RespectBrowserAcceptHeader = true;

setupAction?.Invoke(options);
});
}

public static void AddCustomSearchParameters(this IServiceCollection services, IEnumerable<ModelInfo.SearchParamDefinition> searchParameters)
{
// Add any user-supplied SearchParameters
Expand Down
32 changes: 0 additions & 32 deletions src/Spark.Engine/Extensions/OperationOutcomeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using Hl7.Fhir.Serialization;
using System;
using System.Collections.Generic;
using System.Net;
Expand All @@ -24,8 +23,6 @@ namespace Spark.Engine.Extensions;

public static class OperationOutcomeExtensions
{
internal static Func<string, string> pascalToCamelCase = (pascalCase) => $"{char.ToLower(pascalCase[0])}{pascalCase.Substring(1)}";

#if NETSTANDARD2_1 || NET6_0_OR_GREATER
public static OperationOutcome AddValidationProblems(this OperationOutcome outcome, Type resourceType, HttpStatusCode code, ValidationProblemDetails validationProblems)
{
Expand Down Expand Up @@ -142,33 +139,4 @@ private static OperationOutcome AddIssue(this OperationOutcome outcome, Operatio
outcome.Issue.Add(item);
return outcome;
}

[Obsolete("Use method with signature HttpResponseMessage ToHttpResponseMessage(this OperationOutcome, ResourceFormat) instead.")]
public static HttpResponseMessage ToHttpResponseMessage(this OperationOutcome outcome, ResourceFormat target, HttpRequestMessage request)
{
return ToHttpResponseMessage(outcome, target);
}

public static HttpResponseMessage ToHttpResponseMessage(this OperationOutcome outcome, ResourceFormat target)
{
// TODO: Remove this method is seems to not be in use.
byte[] data = null;
if (target == ResourceFormat.Xml)
{
FhirXmlSerializer serializer = new FhirXmlSerializer();
data = serializer.SerializeToBytes(outcome);
}
else if (target == ResourceFormat.Json)
{
FhirJsonSerializer serializer = new FhirJsonSerializer();
data = serializer.SerializeToBytes(outcome);
}
HttpResponseMessage response = new HttpResponseMessage
{
Content = new ByteArrayContent(data)
};
SetContentHeaders(response, target);

return response;
}
}
20 changes: 15 additions & 5 deletions src/Spark.Engine/FhirResponseFactory/FhirResponseFactory.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/*
/*
* Copyright (c) 2015-2018, Firely <[email protected]>
* Copyright (c) 2019-2025, Incendi <[email protected]>
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/

using System;
using System.Collections.Generic;
using System.Linq;
using Hl7.Fhir.Model;
using Spark.Engine.Core;
using Spark.Engine.Extensions;
using Spark.Engine.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Spark.Engine.FhirResponseFactory;

Expand All @@ -26,6 +26,13 @@ public FhirResponseFactory(ILocalhost localhost, IFhirResponseInterceptorRunner
_interceptorRunner = interceptorRunner;
}

public FhirResponse<T> GetFhirResponse<T>(Entry entry, IKey key = null, IEnumerable<object> parameters = null)
where T : Resource
{
FhirResponse response = GetFhirResponse(entry, key, parameters);
return response != null ? new FhirResponse<T>(response.StatusCode, key, response.Resource as T) : null;
}

public FhirResponse GetFhirResponse(Entry entry, IKey key = null, IEnumerable<object> parameters = null)
{
if (entry == null)
Expand All @@ -47,6 +54,9 @@ public FhirResponse GetFhirResponse(Entry entry, IKey key = null, IEnumerable<ob
return response ?? Respond.WithResource(entry);
}

public FhirResponse<T> GetFhirResponse<T>(Entry entry, IKey key = null, params object[] parameters)
where T : Resource => GetFhirResponse<T>(entry, key, parameters.ToList());

public FhirResponse GetFhirResponse(Entry entry, IKey key = null, params object[] parameters)
{
return GetFhirResponse(entry, key, parameters.ToList());
Expand Down
12 changes: 8 additions & 4 deletions src/Spark.Engine/FhirResponseFactory/IFhirResponseFactory.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
/*
/*
* Copyright (c) 2016-2018, Firely <[email protected]>
* Copyright (c) 2019-2025, Incendi <[email protected]>
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/

using System;
using System.Collections.Generic;
using Hl7.Fhir.Model;
using Spark.Engine.Core;
using System;
using System.Collections.Generic;

namespace Spark.Engine.FhirResponseFactory;

public interface IFhirResponseFactory
{
FhirResponse<T> GetFhirResponse<T>(Entry entry, IKey key = null, IEnumerable<object> parameters = null)
where T : Resource;
FhirResponse GetFhirResponse(Entry entry, IKey key = null, IEnumerable<object> parameters = null);
FhirResponse<T> GetFhirResponse<T>(Entry entry, IKey key = null, params object[] parameters)
where T : Resource;
FhirResponse GetFhirResponse(Entry entry, IKey key = null, params object[] parameters);
FhirResponse GetMetadataResponse(Entry entry, IKey key = null);
FhirResponse GetFhirResponse(IList<Entry> interactions, Bundle.BundleType bundleType);
Expand Down
15 changes: 0 additions & 15 deletions src/Spark.Engine/Formatters/NetCore/ResourceJsonInputFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,6 @@ public ResourceJsonInputFormatter(FhirJsonParser parser, ArrayPool<char> charPoo
}
}

[Obsolete("This constructor is obsolete. Please use constructor with signature ctor(FhirJsonParser, ArrayPool<char>)")]
public ResourceJsonInputFormatter()
{
_parser = new FhirJsonParser();
_charPool = new JsonArrayPool(ArrayPool<char>.Shared);

SupportedEncodings.Clear();
SupportedEncodings.Add(Encoding.UTF8);

foreach (var mediaType in FhirMediaType.JsonMimeTypes)
{
SupportedMediaTypes.Add(mediaType);
}
}

protected override bool CanReadType(Type type)
{
return typeof(Resource).IsAssignableFrom(type);
Expand Down
14 changes: 0 additions & 14 deletions src/Spark.Engine/Formatters/NetCore/ResourceXmlInputFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,6 @@ public ResourceXmlInputFormatter(FhirXmlParser parser)
}
}

[Obsolete("This constructor is obsolete. Please use constructor with signature ctor(FhirXmlParser)")]
public ResourceXmlInputFormatter()
{
_parser = new FhirXmlParser();

SupportedEncodings.Clear();
SupportedEncodings.Add(Encoding.UTF8);

foreach (var mediaType in FhirMediaType.XmlMimeTypes)
{
SupportedMediaTypes.Add(mediaType);
}
}

protected override bool CanReadType(Type type)
{
return typeof(Resource).IsAssignableFrom(type);
Expand Down
3 changes: 3 additions & 0 deletions src/Spark.Engine/Service/Abstractions/FhirServiceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ protected static void ValidateKey(IKey key, bool withVersion = false)
public virtual Task<FhirResponse> HistoryAsync(IKey key, HistoryParameters parameters) => throw new NotImplementedException();
public virtual Task<FhirResponse> PutAsync(IKey key, Resource resource) => throw new NotImplementedException();
public virtual Task<FhirResponse> PutAsync(Entry entry) => throw new NotImplementedException();
public virtual Task<FhirResponse<T>> ReadAsync<T>(IKey key, ConditionalHeaderParameters parameters = null)
where T : Resource => throw new NotImplementedException();
public virtual Task<FhirResponse> ReadAsync(IKey key, ConditionalHeaderParameters parameters = null) => throw new NotImplementedException();
public virtual Task<FhirResponse> ReadMetaAsync(IKey key) => throw new NotImplementedException();
public virtual Task<FhirResponse> SearchAsync(string type, SearchParams searchCommand, int pageIndex = 0) => throw new NotImplementedException();
Expand All @@ -87,6 +89,7 @@ protected static void ValidateKey(IKey key, bool withVersion = false)
public virtual Task<FhirResponse> UpdateAsync(IKey key, Resource resource) => throw new NotImplementedException();
public virtual Task<FhirResponse> PatchAsync(IKey key, Parameters patch) => throw new NotImplementedException();
public virtual Task<FhirResponse> ValidateOperationAsync(IKey key, Resource resource) => throw new NotImplementedException();
public virtual Task<FhirResponse<T>> VersionReadAsync<T>(IKey key) where T : Resource => throw new NotImplementedException();
public virtual Task<FhirResponse> VersionReadAsync(IKey key) => throw new NotImplementedException();
public virtual Task<FhirResponse> VersionSpecificUpdateAsync(IKey versionedKey, Resource resource) => throw new NotImplementedException();
public virtual Task<FhirResponse> EverythingAsync(IKey key) => throw new NotImplementedException();
Expand Down
Loading