Skip to content

Commit

Permalink
Updates package 'Hl7.Fhir.STU3' to version '1.1.3' (#291)
Browse files Browse the repository at this point in the history
* Updates package 'Hl7.Fhir.STU3' to version '1.1.3'
* Fixes test GivenAFhirObjectAndXmlContentType_WhenSerializing_ThenTheObjectIsSerializedToTheResponseStream
* Keeps PermissiveParsing = true behavior
* ResourceDeserializer is no longer static
  • Loading branch information
MicrosoftHealthService authored and brendankowitz committed Mar 15, 2019
1 parent 36e6a4c commit 689eec8
Show file tree
Hide file tree
Showing 20 changed files with 122 additions and 49 deletions.
4 changes: 2 additions & 2 deletions THIRDPARTYNOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,10 @@ This file is based on or incorporates material from the projects listed below (T
>
> END OF TERMS AND CONDITIONS
## Hl7.Fhir.STU3 0.96.0
## Hl7.Fhir.STU3 1.1.3
* Component Source: https://github.com/ewoutkramer/fhir-net-api/
* Component Copyright and License:
> Copyright (c) 2018, HL7, Firely ([email protected]), Microsoft Open Technologies
> Copyright (c) 2013-2019, HL7, Firely ([email protected]), Microsoft Open Technologies
> and contributors. See the file CONTRIBUTORS for details
>
> All rights reserved.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@ public void GivenAFhirObjectAndXmlContentType_WhenCheckingCanWrite_ThenTrueShoul
[Fact]
public async System.Threading.Tasks.Task GivenAFhirObjectAndXmlContentType_WhenSerializing_ThenTheObjectIsSerializedToTheResponseStream()
{
var formatter = new FhirXmlOutputFormatter(new FhirXmlSerializer(), NullLogger<FhirXmlOutputFormatter>.Instance);
var serializer = new FhirXmlSerializer();
var formatter = new FhirXmlOutputFormatter(serializer, NullLogger<FhirXmlOutputFormatter>.Instance);

var resource = new OperationOutcome();
var serializer = new FhirXmlSerializer();

var defaultHttpContext = new DefaultHttpContext();
defaultHttpContext.Request.ContentType = ContentType.XML_CONTENT_HEADER;
var responseBody = new MemoryStream();
defaultHttpContext.Response.Body = responseBody;

var writerFactory = Substitute.For<Func<Stream, Encoding, TextWriter>>();
writerFactory.Invoke(Arg.Any<Stream>(), Arg.Any<Encoding>()).Returns(p => new StreamWriter(p.ArgAt<Stream>(0)));
writerFactory.Invoke(Arg.Any<Stream>(), Arg.Any<Encoding>()).Returns(p => new StreamWriter(p.ArgAt<Stream>(0), p.ArgAt<Encoding>(1)));

await formatter.WriteResponseBodyAsync(
new OutputFormatterWriteContext(
Expand All @@ -61,7 +61,16 @@ await formatter.WriteResponseBodyAsync(
resource),
Encoding.UTF8);

Assert.Equal(serializer.SerializeToString(resource), Encoding.UTF8.GetString(responseBody.ToArray()));
string expectedString;
using (var stream = new MemoryStream())
using (var sw = new StreamWriter(stream, Encoding.UTF8))
using (var writer = new XmlTextWriter(sw))
{
serializer.Serialize(resource, writer);
expectedString = Encoding.UTF8.GetString(stream.ToArray());
}

Assert.Equal(expectedString, Encoding.UTF8.GetString(responseBody.ToArray()));

responseBody.Dispose();
}
Expand Down
17 changes: 16 additions & 1 deletion src/Microsoft.Health.Fhir.Api/Modules/FhirModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System;
using System.Collections.Generic;
using EnsureThat;
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using Hl7.Fhir.Serialization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
Expand All @@ -18,8 +20,10 @@
using Microsoft.Health.Fhir.Api.Features.Filters;
using Microsoft.Health.Fhir.Api.Features.Formatters;
using Microsoft.Health.Fhir.Api.Features.Security;
using Microsoft.Health.Fhir.Core.Features;
using Microsoft.Health.Fhir.Core.Features.Conformance;
using Microsoft.Health.Fhir.Core.Features.Context;
using Microsoft.Health.Fhir.Core.Features.Persistence;
using Microsoft.Health.Fhir.Core.Features.Validation.Narratives;

namespace Microsoft.Health.Fhir.Api.Modules
Expand All @@ -42,7 +46,7 @@ public void Load(IServiceCollection services)
{
EnsureArg.IsNotNull(services, nameof(services));

var jsonParser = new FhirJsonParser();
var jsonParser = new FhirJsonParser(DefaultParserSettings.Settings);
var jsonSerializer = new FhirJsonSerializer();

var xmlParser = new FhirXmlParser();
Expand All @@ -53,6 +57,17 @@ public void Load(IServiceCollection services)
services.AddSingleton(xmlParser);
services.AddSingleton(xmlSerializer);

services.AddSingleton<IReadOnlyDictionary<ResourceFormat, Func<string, Resource>>>(x =>
{
return new Dictionary<ResourceFormat, Func<string, Resource>>
{
{ ResourceFormat.Json, str => jsonParser.Parse<Resource>(str) },
{ ResourceFormat.Xml, str => xmlParser.Parse<Resource>(str) },
};
});

services.AddSingleton<ResourceDeserializer>();

services.Add<FormatterConfiguration>()
.Singleton()
.AsSelf()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Hl7.Fhir.Model;
using Hl7.Fhir.Serialization;
using Microsoft.Health.Fhir.Core.Exceptions;
using Microsoft.Health.Fhir.Core.Features;
using Microsoft.Health.Fhir.Core.Features.Definition;
using Microsoft.Health.Fhir.Tests.Common;
using Xunit;
Expand All @@ -17,7 +18,7 @@ namespace Microsoft.Health.Fhir.Core.UnitTests.Features.Definition
{
public class SearchParameterDefinitionBuilderTests
{
private readonly FhirJsonParser _jsonParser = new FhirJsonParser();
private readonly FhirJsonParser _jsonParser = new FhirJsonParser(DefaultParserSettings.Settings);

private readonly SearchParameterDefinitionBuilder _builderWithInvalidEntries;
private readonly SearchParameterDefinitionBuilder _builderWithInvalidDefinitions;
Expand All @@ -31,9 +32,7 @@ public SearchParameterDefinitionBuilderTests()
}

[Theory]
[InlineData("SearchParametersWithNullEntry", "FHIR Serialization requires an element to have non-null data (at path 'entry[0]')")]
[InlineData("SearchParametersWithInvalidType", "Literal '' is not a valid value for enumeration 'SearchParamType'")]
[InlineData("SearchParametersWithInvalidBase", "Literal '' is not a valid value for enumeration 'ResourceType'")]
[InlineData("SearchParametersWithInvalidBase", "bundle.entry[http://hl7.org/fhir/SearchParameter/DomainResource-text].resource.base is not defined.")]
public void GivenAnInvalidSearchParameterDefinitionFile_WhenBuilt_ThenInvalidDefinitionExceptionShouldBeThrown(string fileName, string expectedIssue)
{
var builder = CreateBuilder(fileName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.Health.Fhir.Core.Features.Routing;
using Microsoft.Health.Fhir.Core.Features.Search;
using Microsoft.Health.Fhir.Core.Models;
using Microsoft.Health.Fhir.Tests.Common;
using NSubstitute;
using Xunit;
using Task = System.Threading.Tasks.Task;
Expand All @@ -40,7 +41,7 @@ public class SearchServiceTests

public SearchServiceTests()
{
_bundleFactory = new BundleFactory(_urlResolver, _fhirRequestContextAccessor);
_bundleFactory = new BundleFactory(_urlResolver, _fhirRequestContextAccessor, Deserializers.ResourceDeserializer);
_dataStore = Substitute.For<IDataStore>();

_searchOptionsFactory.Create(Arg.Any<string>(), Arg.Any<IReadOnlyList<Tuple<string, string>>>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void GivenARawResourceOfUnknownType_WhenDeserializing_ThenANotSupportedEx
var raw = new RawResource("{}", ResourceFormat.Unknown);
var wrapper = new ResourceWrapper("id1", "version1", "Observation", raw, new ResourceRequest("http://fhir", HttpMethod.Post), Clock.UtcNow, false, null, null, null);

Assert.Throws<NotSupportedException>(() => ResourceDeserializer.Deserialize(wrapper));
Assert.Throws<NotSupportedException>(() => Deserializers.ResourceDeserializer.Deserialize(wrapper));
}

[Fact]
Expand All @@ -38,7 +38,7 @@ public void GivenARawResource_WhenDeserializingFromJson_ThenTheObjectIsReturned(
observation.Id = "id1";
var wrapper = new ResourceWrapper(observation, _rawResourceFactory.Create(observation), new ResourceRequest("http://fhir", HttpMethod.Post), false, null, null, null);

var newObject = ResourceDeserializer.Deserialize(wrapper);
var newObject = Deserializers.ResourceDeserializer.Deserialize(wrapper);

Assert.Equal(observation.Id, newObject.Id);
Assert.Equal(observation.VersionId, newObject.VersionId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public ResourceHandlerTests()

collection.Add(x => new CreateResourceHandler(_dataStore, lazyConformanceProvider, _resourceWrapperFactory)).Singleton().AsSelf().AsImplementedInterfaces();
collection.Add(x => new UpsertResourceHandler(_dataStore, lazyConformanceProvider, _resourceWrapperFactory)).Singleton().AsSelf().AsImplementedInterfaces();
collection.Add(x => new GetResourceHandler(_dataStore, lazyConformanceProvider, _resourceWrapperFactory)).Singleton().AsSelf().AsImplementedInterfaces();
collection.Add(x => new GetResourceHandler(_dataStore, lazyConformanceProvider, _resourceWrapperFactory, Deserializers.ResourceDeserializer)).Singleton().AsSelf().AsImplementedInterfaces();
collection.Add(x => new DeleteResourceHandler(_dataStore, lazyConformanceProvider, _resourceWrapperFactory)).Singleton().AsSelf().AsImplementedInterfaces();

ServiceProvider provider = collection.BuildServiceProvider();
Expand Down
14 changes: 14 additions & 0 deletions src/Microsoft.Health.Fhir.Core/Features/DefaultParserSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------

using Hl7.Fhir.Serialization;

namespace Microsoft.Health.Fhir.Core.Features
{
internal class DefaultParserSettings
{
public static readonly ParserSettings Settings = new ParserSettings { PermissiveParsing = true };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,33 @@
// -------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using EnsureThat;
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using Hl7.Fhir.Serialization;

namespace Microsoft.Health.Fhir.Core.Features.Persistence
{
public static class ResourceDeserializer
public class ResourceDeserializer
{
private static readonly FhirXmlParser FhirXmlParser = new FhirXmlParser();
private static readonly FhirJsonParser FhirJsonParser = new FhirJsonParser();
private readonly IReadOnlyDictionary<ResourceFormat, Func<string, Resource>> _deserializers;

public static Resource Deserialize(ResourceWrapper resourceWrapper)
public ResourceDeserializer(IReadOnlyDictionary<ResourceFormat, Func<string, Resource>> deserializers)
{
EnsureArg.IsNotNull(deserializers, nameof(deserializers));

_deserializers = deserializers;
}

public ResourceDeserializer(params (ResourceFormat Format, Func<string, Resource> Func)[] deserializers)
{
EnsureArg.IsNotNull(deserializers, nameof(deserializers));

_deserializers = deserializers.ToDictionary(x => x.Format, x => x.Func);
}

public Resource Deserialize(ResourceWrapper resourceWrapper)
{
EnsureArg.IsNotNull(resourceWrapper, nameof(resourceWrapper));

Expand All @@ -28,25 +42,16 @@ public static Resource Deserialize(ResourceWrapper resourceWrapper)
return resource;
}

internal static Resource DeserializeRaw(RawResource rawResource)
internal Resource DeserializeRaw(RawResource rawResource)
{
EnsureArg.IsNotNull(rawResource, nameof(rawResource));

Resource resource;

switch (rawResource.Format)
if (!_deserializers.TryGetValue(rawResource.Format, out var deserializer))
{
case ResourceFormat.Xml:
resource = FhirXmlParser.Parse<Resource>(rawResource.Data);
break;
case ResourceFormat.Json:
resource = FhirJsonParser.Parse<Resource>(rawResource.Data);
break;
default:
throw new NotSupportedException();
throw new NotSupportedException();
}

return resource;
return deserializer(rawResource.Data);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@ namespace Microsoft.Health.Fhir.Core.Features.Resources.Get
{
public class GetResourceHandler : BaseResourceHandler, IRequestHandler<GetResourceRequest, GetResourceResponse>
{
private readonly ResourceDeserializer _deserializer;

public GetResourceHandler(
IDataStore dataStore,
Lazy<IConformanceProvider> conformanceProvider,
IResourceWrapperFactory resourceWrapperFactory)
IResourceWrapperFactory resourceWrapperFactory,
ResourceDeserializer deserializer)
: base(dataStore, conformanceProvider, resourceWrapperFactory)
{
EnsureArg.IsNotNull(deserializer, nameof(deserializer));

_deserializer = deserializer;
}

public async Task<GetResourceResponse> Handle(GetResourceRequest message, CancellationToken cancellationToken)
Expand Down Expand Up @@ -60,7 +66,7 @@ await ConformanceProvider.Value.CanReadHistory(key.ResourceType, cancellationTok
throw new ResourceGoneException(new ResourceKey(currentDoc.ResourceTypeName, currentDoc.ResourceId, currentDoc.Version));
}

return new GetResourceResponse(ResourceDeserializer.Deserialize(currentDoc));
return new GetResourceResponse(_deserializer.Deserialize(currentDoc));
}

protected override void AddResourceCapability(ListedCapabilityStatement statement, ResourceType resourceType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ public class BundleFactory : IBundleFactory
{
private readonly IUrlResolver _urlResolver;
private readonly IFhirRequestContextAccessor _fhirRequestContextAccessor;
private readonly ResourceDeserializer _deserializer;

public BundleFactory(IUrlResolver urlResolver, IFhirRequestContextAccessor fhirRequestContextAccessor)
public BundleFactory(IUrlResolver urlResolver, IFhirRequestContextAccessor fhirRequestContextAccessor, ResourceDeserializer deserializer)
{
EnsureArg.IsNotNull(urlResolver, nameof(urlResolver));
EnsureArg.IsNotNull(fhirRequestContextAccessor, nameof(fhirRequestContextAccessor));
EnsureArg.IsNotNull(deserializer, nameof(deserializer));

_urlResolver = urlResolver;
_fhirRequestContextAccessor = fhirRequestContextAccessor;
_deserializer = deserializer;
}

public Bundle CreateSearchBundle(IEnumerable<Tuple<string, string>> unsupportedSearchParameters, SearchResult result)
Expand All @@ -37,7 +40,7 @@ public Bundle CreateSearchBundle(IEnumerable<Tuple<string, string>> unsupportedS
{
IEnumerable<Bundle.EntryComponent> entries = result.Results.Select(r =>
{
Resource resource = ResourceDeserializer.Deserialize(r);
Resource resource = _deserializer.Deserialize(r);

return new Bundle.EntryComponent
{
Expand Down Expand Up @@ -85,7 +88,7 @@ public Bundle CreateHistoryBundle(IEnumerable<Tuple<string, string>> unsupported
{
IEnumerable<Bundle.EntryComponent> entries = result.Results.Select(r =>
{
Resource resource = ResourceDeserializer.Deserialize(r);
Resource resource = _deserializer.Deserialize(r);
var hasVerb = Enum.TryParse(r.Request?.Method, true, out Bundle.HTTPVerb httpVerb);

return new Bundle.EntryComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61" />
<PackageReference Include="Hl7.Fhir.STU3" Version="0.96.0" />
<PackageReference Include="Hl7.Fhir.STU3" Version="1.1.3" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.Health.Fhir.Core/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: InternalsVisibleTo("Microsoft.Health.Fhir.CosmosDb")]
[assembly: InternalsVisibleTo("Microsoft.Health.Fhir.Api")]
[assembly: InternalsVisibleTo("Microsoft.Health.Fhir.CosmosDb.UnitTests")]
[assembly: InternalsVisibleTo("Microsoft.Health.Fhir.Core.UnitTests")]
[assembly: InternalsVisibleTo("Microsoft.Health.Fhir.Tests.Common")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void GivenAResource_WhenCreatingAResourceWrapper_ThenMetaPropertiesAreCor
using (Mock.Property(() => Clock.UtcNowFunc, () => lastModified))
{
var wrapper = new ResourceWrapper(observation, _rawResourceFactory.Create(observation), new ResourceRequest("http://fhir", HttpMethod.Post), false, null, null, null);
var resource = ResourceDeserializer.Deserialize(wrapper);
var resource = Deserializers.ResourceDeserializer.Deserialize(wrapper);

Assert.Equal(observation.VersionId, resource.Meta.VersionId);
Assert.Equal(lastModified, resource.Meta.LastUpdated);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61" />
<PackageReference Include="Hl7.Fhir.STU3" Version="0.96.0" />
<PackageReference Include="Hl7.Fhir.STU3" Version="1.1.3" />
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.2.3" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.2.0" />
</ItemGroup>
Expand Down
21 changes: 21 additions & 0 deletions src/Microsoft.Health.Fhir.Tests.Common/Deserializers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------

using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using Hl7.Fhir.Serialization;
using Microsoft.Health.Fhir.Core.Features;
using Microsoft.Health.Fhir.Core.Features.Persistence;

namespace Microsoft.Health.Fhir.Tests.Common
{
public static class Deserializers
{
private static readonly FhirJsonParser JsonParser = new FhirJsonParser(DefaultParserSettings.Settings);

public static ResourceDeserializer ResourceDeserializer => new ResourceDeserializer(
(ResourceFormat.Json, str => JsonParser.Parse<Resource>(str)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Hl7.Fhir.STU3" Version="0.96.0" />
<PackageReference Include="Hl7.Fhir.STU3" Version="1.1.3" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" />
<PackageReference Include="NSubstitute" Version="4.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
Expand Down
Loading

0 comments on commit 689eec8

Please sign in to comment.