private static Bundle ParseJSON(string content, bool permissive) { Bundle bundle = null; // Grab all errors found by visiting all nodes and report if not permissive if (!permissive) { List <string> entries = new List <string>(); ISourceNode node = FhirJsonNode.Parse(content, "Bundle", new FhirJsonParsingSettings { PermissiveParsing = permissive }); foreach (Hl7.Fhir.Utility.ExceptionNotification problem in node.VisitAndCatch()) { entries.Add(problem.Message); } if (entries.Count > 0) { throw new System.ArgumentException(String.Join("; ", entries).TrimEnd()); } } // Try Parse try { FhirJsonParser parser = new FhirJsonParser(GetParserSettings(permissive)); bundle = parser.Parse <Bundle>(content); } catch (Exception e) { throw new System.ArgumentException(e.Message); } return(bundle); }
public void AnnotationsFromParsingTest() { var _sdsProvider = new PocoStructureDefinitionSummaryProvider(); var patientJson = "{\"resourceType\":\"Patient\", \"active\":\"true\"}"; var patient = FhirJsonNode.Parse(patientJson); var typedPatient = patient.ToTypedElement(_sdsProvider, "Patient"); var sourceNode = typedPatient.ToSourceNode(); var result = patient.Annotation <ISourceNode>(); Assert.IsNotNull(result); Assert.AreEqual(typeof(FhirJsonNode), result.GetType(), "ISourceNode is provided by FhirJsonNode"); Assert.AreSame(patient, result); var result2 = sourceNode.Annotation <ISourceNode>(); Assert.IsNotNull(result2); Assert.AreEqual(typeof(TypedElementToSourceNodeAdapter), result2.GetType(), "Now ISourceNode is provided by TypedElementToSourceNodeAdapter"); Assert.AreSame(sourceNode, result2); var result3 = sourceNode.Annotation <IResourceTypeSupplier>(); Assert.IsNotNull(result3); Assert.AreEqual(typeof(TypedElementToSourceNodeAdapter), result3.GetType()); }
internal static BundleWrapper ReadEmbeddedSearchParameters( string embeddedResourceName, IModelInfoProvider modelInfoProvider, string embeddedResourceNamespace = null, Assembly assembly = null) { using Stream stream = modelInfoProvider.OpenVersionedFileStream(embeddedResourceName, embeddedResourceNamespace, assembly); using TextReader reader = new StreamReader(stream); using JsonReader jsonReader = new JsonTextReader(reader); try { ISourceNode sourceNode = FhirJsonNode.Read(jsonReader); return(new BundleWrapper(modelInfoProvider.ToTypedElement(sourceNode))); } catch (FormatException ex) { var issue = new OperationOutcomeIssue( OperationOutcomeConstants.IssueSeverity.Fatal, OperationOutcomeConstants.IssueType.Invalid, ex.Message); throw new InvalidDefinitionException( Core.Resources.SearchParameterDefinitionContainsInvalidEntry, new OperationOutcomeIssue[] { issue }); } }
internal override ResourceElement GetPatchedResourceElement(ResourceWrapper resourceToPatch) { var resourceJsonNode = (FhirJsonNode)FhirJsonNode.Parse(resourceToPatch.RawResource.Data); try { PatchDocument.ApplyTo(resourceJsonNode.JsonObject); } catch (JsonPatchException e) { throw new RequestNotValidException(e.Message, OperationOutcomeConstants.IssueType.Processing); } catch (ArgumentNullException e) { throw new RequestNotValidException(e.Message, OperationOutcomeConstants.IssueType.Processing); } Resource resourcePoco; try { resourcePoco = resourceJsonNode .ToTypedElement(ModelInfoProvider.StructureDefinitionSummaryProvider) .ToPoco <Resource>(); } catch (Exception e) { throw new RequestNotValidException(string.Format(Core.Resources.PatchResourceError, e.Message)); } return(resourcePoco.ToResourceElement()); }
public void CompareToOtherElementNavigator() { var json = TestDataHelper.ReadTestData("TestPatient.json"); var xml = TestDataHelper.ReadTestData("TestPatient.xml"); var pocoP = (new FhirJsonParser()).Parse <Patient>(json).ToTypedElement(); var jsonP = FhirJsonNode.Parse(json, settings: new FhirJsonParsingSettings { AllowJsonComments = true }) .ToTypedElement(new PocoStructureDefinitionSummaryProvider()); var xmlP = FhirXmlNode.Parse(xml).ToTypedElement(new PocoStructureDefinitionSummaryProvider()); doCompare(pocoP, jsonP, "poco<->json"); doCompare(pocoP, xmlP, "poco<->xml"); void doCompare(ITypedElement one, ITypedElement two, string what) { var compare = one.IsEqualTo(two); if (compare.Success == false) { Debug.WriteLine($"{what}: Difference in {compare.Details} at {compare.FailureLocation}"); Assert.Fail(); } } }
public Task <OperationDefinitionResponse> Handle(OperationDefinitionRequest request, CancellationToken cancellationToken) { using Stream stream = DataLoader.OpenOperationDefinitionFileStream($"{request.OperationName}.json"); using TextReader reader = new StreamReader(stream); using JsonReader jsonReader = new JsonTextReader(reader); ISourceNode result = FhirJsonNode.Read(jsonReader); ITypedElement operationDefinition = result.ToTypedElement(_modelInfoProvider.StructureDefinitionSummaryProvider); return(Task.FromResult(new OperationDefinitionResponse(operationDefinition.ToResourceElement()))); }
private ITypedElement ParseJsonToTypedElement(string json) { try { return(FhirJsonNode.Parse(json).ToTypedElement(_provider)); } catch (Exception ex) { throw new InvalidInputException($"The input FHIR resource JSON is invalid.", ex); } }
public void Start() { // The json file is a bundle compiled from the compartment definitions currently defined by HL7. // The definitions are available at https://www.hl7.org/fhir/compartmentdefinition.html. using Stream stream = _modelInfoProvider.OpenVersionedFileStream("compartment.json"); using TextReader reader = new StreamReader(stream); using JsonReader jsonReader = new JsonTextReader(reader); var bundle = new BundleWrapper(FhirJsonNode.Read(jsonReader).ToTypedElement(_modelInfoProvider.StructureDefinitionSummaryProvider)); Build(bundle); }
public ResourceElement Patch(ResourceWrapper resourceToPatch, JsonPatchDocument patchDocument, WeakETag weakETag) { EnsureArg.IsNotNull(resourceToPatch, nameof(resourceToPatch)); Validate(resourceToPatch, weakETag, patchDocument); var node = (FhirJsonNode)FhirJsonNode.Parse(resourceToPatch.RawResource.Data); // Capture the state of properties that are immutable ITypedElement resource = node.ToTypedElement(_modelInfoProvider.StructureDefinitionSummaryProvider); (string path, object result)[] preState = _immutableProperties.Select(x => (path: x, result: resource.Scalar(x))).ToArray();
public ITypedElement DeserializeToElement( string resourceContent, FhirJsonParsingSettings settings = null) { if (_fhirVersion == FhirVersion.Stu3) { return(FhirJsonNode.Parse(resourceContent, settings: settings).ToTypedElement(_stu3Provider)); } else { return(FhirJsonNode.Parse(resourceContent).ToTypedElement(_r4Provider)); } }
public void PreservesParsingExceptionDetails() { try { var nav = FhirJsonNode.Parse("<bla", "test"); var dummy = nav.Text; Assert.Fail(); } catch (FormatException fe) { Assert.IsInstanceOfType(fe.InnerException, typeof(JsonException)); } }
public void TryInvalidUntypedSource() { var jsonNav = FhirJsonNode.Parse("{ 'resourceType': 'Patient', 'active':true }"); try { var output = jsonNav.ToXml(); Assert.Fail(); } catch (NotSupportedException) { } }
internal static ITypedElement ParseToTypedElement(string json, IStructureDefinitionSummaryProvider provider, string rootName = null, FhirJsonParsingSettings settings = null, TypedElementSettings tnSettings = null) { if (json == null) { throw Error.ArgumentNull(nameof(json)); } if (provider == null) { throw Error.ArgumentNull(nameof(provider)); } return(FhirJsonNode.Parse(json, rootName, settings).ToTypedElement(provider, null, tnSettings)); }
public void CatchNullErrors() { var nav = FhirJsonNode.Parse("{ 'a': null }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ '_a': null }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': null, '_a' : null }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': [null] }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': [null], '_a': [null] }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); }
public void SourceNodeFromElementNodeReturnsResourceTypeSupplier() { var _sdsProvider = new PocoStructureDefinitionSummaryProvider(); var patientJson = "{\"resourceType\":\"Patient\", \"active\":\"true\"}"; var patientNode = FhirJsonNode.Parse(patientJson); var typedPatient = patientNode.ToTypedElement(_sdsProvider, "Patient"); var elementNode = ElementNode.FromElement(typedPatient); var adapter = elementNode.ToSourceNode(); Assert.AreEqual(typeof(TypedElementToSourceNodeAdapter), adapter.GetType(), "ISourceNode is provided by TypedElementToSourceNodeAdapter"); var result = adapter.Annotation <IResourceTypeSupplier>(); Assert.IsNotNull(result); Assert.AreEqual(typeof(TypedElementToSourceNodeAdapter), result.GetType()); Assert.AreEqual("Patient", adapter.GetResourceTypeIndicator()); Assert.AreSame(adapter, result); }
public void CatchesArrayMismatch() { var nav = FhirJsonNode.Parse("{ 'a': [2,3,4], '_a' : [2,4] }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': 2, '_a' : [2] }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': [2,3,4], '_a' : {} }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ '_a': [4,5,6] }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': [2,3,4] }", "test"); Assert.IsTrue(nav.Children().Any()); nav = FhirJsonNode.Parse("{ 'a': [null,2], '_a' : [{'active':true},null] }", "test"); Assert.IsTrue(nav.Children().Any()); }
public void CannotUseAbstractType() { var bundleJson = "{\"resourceType\":\"Bundle\", \"entry\":[{\"fullUrl\":\"http://example.org/Patient/1\"}]}"; var bundle = FhirJsonNode.Parse(bundleJson); var typedBundle = bundle.ToTypedElement(provider, "Bundle"); //Type of entry is BackboneElement, but you can't set that, see below. Assert.Equal("BackboneElement", typedBundle.Select("$this.entry[0]").First().InstanceType); var entry = SourceNode.Node("entry", SourceNode.Valued("fullUrl", "http://example.org/Patient/1")); try { var typedEntry = entry.ToTypedElement(provider, "Element"); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail("Should have thrown on invalid Div format"); } catch (ArgumentException) { } }
public ITypedElement Build() { // To build a CapabilityStatement we use a custom JsonConverter that serializes // the ListedCapabilityStatement into a CapabilityStatement poco var json = JsonConvert.SerializeObject(_statement, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), Converters = new List <JsonConverter> { new DefaultOptionHashSetJsonConverter(), new EnumLiteralJsonConverter(), }, NullValueHandling = NullValueHandling.Ignore, }); ISourceNode jsonStatement = FhirJsonNode.Parse(json); // Using a version specific StructureDefinitionSummaryProvider ensures the metadata to be // compatible with the current FhirSerializer/output formatter. return(jsonStatement.ToTypedElement(_modelInfoProvider.StructureDefinitionSummaryProvider)); }
private static async Task <ITypedElement> parseResourceAsync(string bodyText, string contentType, IStructureDefinitionSummaryProvider provider, bool throwOnFormatException) { if (bodyText == null) { throw Error.ArgumentNull(nameof(bodyText)); } if (provider == null) { throw Error.ArgumentNull(nameof(provider)); } var fhirType = ContentType.GetResourceFormatFromContentType(contentType); if (fhirType == ResourceFormat.Unknown) { throw new UnsupportedBodyTypeException( "Endpoint returned a body with contentType '{0}', while a valid FHIR xml/json body type was expected. Is this a FHIR endpoint?" .FormatWith(contentType), contentType, bodyText); } if (!SerializationUtil.ProbeIsJson(bodyText) && !SerializationUtil.ProbeIsXml(bodyText)) { throw new UnsupportedBodyTypeException( "Endpoint said it returned '{0}', but the body is not recognized as either xml or json.".FormatWith(contentType), contentType, bodyText); } try { return((fhirType == ResourceFormat.Json) ? (await FhirJsonNode.ParseAsync(bodyText).ConfigureAwait(false)).ToTypedElement(provider) : (await FhirXmlNode.ParseAsync(bodyText).ConfigureAwait(false)).ToTypedElement(provider)); } catch (FormatException) when(!throwOnFormatException) { return(null); } }
public void CatchesUnsupportedFeatures() { var nav = FhirJsonNode.Parse("{ 'a': ' ' }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': {}, '_a' : {} }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': {'active':true}, '_a': {'dummy':4} }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ '_a' : {} }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': 3, '_a' : 4 }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ 'a': new DateTime() }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); nav = FhirJsonNode.Parse("{ '_a': new DateTime() }", "test"); Assert.ThrowsException <FormatException>(() => nav.VisitAll()); }
public ITypedElement Resolve(string reference) { if (string.IsNullOrWhiteSpace(reference)) { return(null); } ReferenceSearchValue parsed = _referenceParser.Parse(reference); if (parsed == null || !_modelInfoProvider.IsKnownResource(parsed.ResourceType)) { return(null); } ISourceNode node = FhirJsonNode.Create( JObject.FromObject( new { resourceType = parsed.ResourceType, id = parsed.ResourceId, })); return(node.ToTypedElement(_modelInfoProvider.StructureDefinitionSummaryProvider)); }
public ITypedElement ToTypedElement(RawResource rawResource) { EnsureArg.IsNotNull(rawResource, nameof(rawResource)); using TextReader reader = new StringReader(rawResource.Data); using JsonReader jsonReader = new JsonTextReader(reader); try { ISourceNode sourceNode = FhirJsonNode.Read(jsonReader); return(sourceNode.ToTypedElement(StructureDefinitionSummaryProvider)); } catch (FormatException ex) { var issue = new OperationOutcomeIssue( OperationOutcomeConstants.IssueSeverity.Fatal, OperationOutcomeConstants.IssueType.Invalid, ex.Message); throw new ResourceNotValidException(new List <OperationOutcomeIssue>() { issue }); } }
public static MockModelInfoProviderBuilder Create(FhirSpecification version) { IModelInfoProvider provider = Substitute.For <IModelInfoProvider>(); provider.Version.Returns(version); // Adds normative types by default var seenTypes = new HashSet <string> { "Binary", "Bundle", "CapabilityStatement", "CodeSystem", "Observation", "OperationOutcome", "Patient", "StructureDefinition", "ValueSet", }; provider.GetResourceTypeNames().Returns(_ => seenTypes.Where(x => !string.IsNullOrEmpty(x)).ToArray()); provider.IsKnownResource(Arg.Any <string>()).Returns(x => provider.GetResourceTypeNames().Contains(x[0])); // Simulate inherited behavior // Some code depends on "InheritedResource".BaseType // This adds the ability to resolve "Resource" as the base type provider.GetTypeForFhirType(Arg.Any <string>()).Returns(p => p.ArgAt <string>(0) == "Resource" ? typeof(ResourceObj) : typeof(InheritedResourceObj)); provider.GetFhirTypeNameForType(Arg.Any <Type>()).Returns(p => p.ArgAt <Type>(0) == typeof(ResourceObj) ? "Resource" : null); // IStructureDefinitionSummaryProvider allows the execution of FHIRPath queries provider.ToTypedElement(Arg.Any <ISourceNode>()) .Returns(p => p.ArgAt <ISourceNode>(0).ToTypedElement(new MockStructureDefinitionSummaryProvider(p.ArgAt <ISourceNode>(0), seenTypes))); provider.ToTypedElement(Arg.Any <RawResource>()) .Returns(r => { using TextReader reader = new StringReader(r.ArgAt <RawResource>(0).Data); using JsonReader jsonReader = new JsonTextReader(reader); ISourceNode sourceNode = FhirJsonNode.Read(jsonReader); return(sourceNode.ToTypedElement(new MockStructureDefinitionSummaryProvider(sourceNode, seenTypes))); }); return(new MockModelInfoProviderBuilder(provider, seenTypes)); }
public void CanUseBackboneTypeForEntry() { var _sdsProvider = new PocoStructureDefinitionSummaryProvider(); var bundleJson = "{\"resourceType\":\"Bundle\", \"entry\":[{\"fullUrl\":\"http://example.org/Patient/1\"}]}"; var bundle = FhirJsonNode.Parse(bundleJson); var typedBundle = bundle.ToTypedElement(_sdsProvider, "Bundle"); //Type of entry is BackboneElement, but you can't set that, see below. Assert.Equal("BackboneElement", typedBundle.Select("$this.entry[0]").First().InstanceType); var entry = SourceNode.Node("entry", SourceNode.Valued("fullUrl", "http://example.org/Patient/1")); //What DOES work: var typedEntry = entry.ToTypedElement(_sdsProvider, "Element"); //But you can't use BackboneElement here, see below. Assert.Equal("Element", typedEntry.InstanceType); //But this leads to a System.ArgumentException: //Type BackboneElement is not a mappable Fhir datatype or resource //Parameter name: type typedEntry = entry.ToTypedElement(_sdsProvider, "BackboneElement"); Assert.Equal("BackboneElement", typedEntry.InstanceType); // Expected to be able to use BackboneElement as type for the entry SourceNode; }
/// <summary> /// Converts the RawResource to an ITypedElement /// </summary> /// <param name="rawResource">The RawResource to convert</param> /// <param name="modelInfoProvider">The IModelInfoProvider to use when converting the RawResource</param> /// <returns>An ITypedElement of the RawResource</returns> public static ITypedElement ToITypedElement(this RawResource rawResource, IModelInfoProvider modelInfoProvider) { EnsureArg.IsNotNull(rawResource, nameof(rawResource)); EnsureArg.IsNotNull(modelInfoProvider, nameof(modelInfoProvider)); using TextReader reader = new StringReader(rawResource.Data); using JsonReader jsonReader = new JsonTextReader(reader); try { ISourceNode sourceNode = FhirJsonNode.Read(jsonReader); return(modelInfoProvider.ToTypedElement(sourceNode)); } catch (FormatException ex) { var issue = new OperationOutcomeIssue( OperationOutcomeConstants.IssueSeverity.Fatal, OperationOutcomeConstants.IssueType.Invalid, ex.Message); throw new InvalidDefinitionException( Core.Resources.SearchParameterDefinitionContainsInvalidEntry, new OperationOutcomeIssue[] { issue }); } }
ISourceNode FhirJsonNodeParse(string json, string rootName) => FhirJsonNode.Parse(json, rootName, new FhirJsonParsingSettings() { PermissiveParsing = false });
/// <inheritdoc /> public void Load(IServiceCollection services) { EnsureArg.IsNotNull(services, nameof(services)); var jsonParser = new FhirJsonParser(DefaultParserSettings.Settings); var jsonSerializer = new FhirJsonSerializer(); var xmlParser = new FhirXmlParser(); var xmlSerializer = new FhirXmlSerializer(); services.AddSingleton(jsonParser); services.AddSingleton(jsonSerializer); services.AddSingleton(xmlParser); services.AddSingleton(xmlSerializer); services.AddSingleton <BundleSerializer>(); FhirPathCompiler.DefaultSymbolTable.AddFhirExtensions(); ResourceElement SetMetadata(Resource resource, string versionId, DateTimeOffset lastModified) { resource.VersionId = versionId; resource.Meta.LastUpdated = lastModified; return(resource.ToResourceElement()); } services.AddSingleton <IReadOnlyDictionary <FhirResourceFormat, Func <string, string, DateTimeOffset, ResourceElement> > >(_ => { return(new Dictionary <FhirResourceFormat, Func <string, string, DateTimeOffset, ResourceElement> > { { FhirResourceFormat.Json, (str, version, lastModified) => { Resource resource = null; var parsed = false; var i = 0; do { try { resource = jsonParser.Parse <Resource>(str); parsed = true; } catch (StructuralTypeException ex) { var match = MessageChecker.Match(ex.Message); if (match.Success && match.Groups.Count == 4 && match.Groups["type"].Value == "date") { i++; if (i > 100) { throw; } var valueToReplace = match.Groups["value"].Value; var location = match.Groups["location"].Value; var replace = valueToReplace.Substring(0, 10); var root = FhirJsonNode.Parse(str, KnownResourceTypes.Resource); var currentNode = root; while (currentNode != null) { foreach (var child in currentNode.Children()) { if (location.StartsWith(child.Location, StringComparison.OrdinalIgnoreCase)) { currentNode = child; break; } } if (currentNode.Location == location) { break; } } (currentNode as FhirJsonNode).JsonValue.Value = replace; str = root.ToJson(); } else { throw; } } }while (!parsed); return SetMetadata(resource, version, lastModified); } }, { FhirResourceFormat.Xml, (str, version, lastModified) => { var resource = xmlParser.Parse <Resource>(str); return SetMetadata(resource, version, lastModified); } }, }); }); services.Add <ResourceDeserializer>() .Singleton() .AsSelf() .AsService <IResourceDeserializer>(); services.Add <FormatterConfiguration>() .Singleton() .AsSelf() .AsService <IPostConfigureOptions <MvcOptions> >(); services.AddSingleton <IFormatParametersValidator, FormatParametersValidator>(); services.AddSingleton <OperationOutcomeExceptionFilterAttribute>(); services.AddSingleton <ValidateFormatParametersAttribute>(); services.AddSingleton <ValidateExportRequestFilterAttribute>(); services.AddSingleton <ValidateReindexRequestFilterAttribute>(); // Support for resolve() FhirPathCompiler.DefaultSymbolTable.AddFhirExtensions(); services.Add <FhirJsonInputFormatter>() .Singleton() .AsSelf() .AsService <TextInputFormatter>(); services.Add <FhirJsonOutputFormatter>() .Singleton() .AsSelf() .AsService <TextOutputFormatter>(); services.Add <FhirRequestContextAccessor>() .Singleton() .AsSelf() .AsService <RequestContextAccessor <IFhirRequestContext> >(); services.AddSingleton <CorrelationIdProvider>(_ => () => Guid.NewGuid().ToString()); // Add conformance provider for implementation metadata. services.Add <SystemConformanceProvider>() .Singleton() .AsSelf() .AsImplementedInterfaces(); services.TypesInSameAssembly(KnownAssemblies.All) .AssignableTo <IProvideCapability>() .Transient() .AsService <IProvideCapability>(); services.AddSingleton <IClaimsExtractor, PrincipalClaimsExtractor>(); ModelExtensions.SetModelInfoProvider(); services.Add(_ => ModelInfoProvider.Instance).Singleton().AsSelf().AsImplementedInterfaces(); // Register a factory to resolve a scope that returns all components that provide capabilities services.AddFactory <IScoped <IEnumerable <IProvideCapability> > >(); // Register pipeline behavior to intercept create/update requests and check presence of provenace header. services.Add <ProvenanceHeaderBehavior>().Scoped().AsSelf().AsImplementedInterfaces(); services.Add <ProvenanceHeaderState>().Scoped().AsSelf().AsImplementedInterfaces(); // Register pipeline behavior to check service permission for CUD actions on StructuredDefinition,ValueSet,CodeSystem, ConceptMap. services.Add <ProfileResourcesBehaviour>().Singleton().AsSelf().AsImplementedInterfaces(); services.AddLazy(); services.AddScoped(); }
public ISourceNode getJsonNodeU(string json, FhirJsonParsingSettings settings = null) => FhirJsonNode.Parse(json, settings: settings);
private List <(string ResourceType, SearchParameterInfo SearchParameter)> ValidateAndGetFlattenedList() { var issues = new List <OperationOutcomeIssue>(); BundleWrapper bundle = null; using (Stream stream = _modelInfoProvider.OpenVersionedFileStream(_embeddedResourceName, _embeddedResourceNamespace, _assembly)) { using TextReader reader = new StreamReader(stream); using JsonReader jsonReader = new JsonTextReader(reader); try { bundle = new BundleWrapper(FhirJsonNode.Read(jsonReader).ToTypedElement(_modelInfoProvider.StructureDefinitionSummaryProvider)); } catch (FormatException ex) { AddIssue(ex.Message); } } EnsureNoIssues(); IReadOnlyList <BundleEntryWrapper> entries = bundle.Entries; // Do the first pass to make sure all resources are SearchParameter. for (int entryIndex = 0; entryIndex < entries.Count; entryIndex++) { // Make sure resources are not null and they are SearchParameter. BundleEntryWrapper entry = entries[entryIndex]; ITypedElement searchParameterElement = entry.Resource; if (searchParameterElement == null || !string.Equals(searchParameterElement.InstanceType, KnownResourceTypes.SearchParameter, StringComparison.OrdinalIgnoreCase)) { AddIssue(Core.Resources.SearchParameterDefinitionInvalidResource, entryIndex); continue; } var searchParameter = new SearchParameterWrapper(searchParameterElement); try { SearchParameterInfo searchParameterInfo = CreateSearchParameterInfo(searchParameter); _uriDictionary.Add(new Uri(searchParameter.Url), searchParameterInfo); } catch (FormatException) { AddIssue(Core.Resources.SearchParameterDefinitionInvalidDefinitionUri, entryIndex); continue; } catch (ArgumentException) { AddIssue(Core.Resources.SearchParameterDefinitionDuplicatedEntry, searchParameter.Url); continue; } } EnsureNoIssues(); var validatedSearchParameters = new List <(string ResourceType, SearchParameterInfo SearchParameter)> { // _type is currently missing from the search params definition bundle, so we inject it in here. (KnownResourceTypes.Resource, new SearchParameterInfo(SearchParameterNames.ResourceType, SearchParamType.Token, SearchParameterNames.ResourceTypeUri, null, "Resource.type().name", null)), }; // Do the second pass to make sure the definition is valid. for (int entryIndex = 0; entryIndex < entries.Count; entryIndex++) { BundleEntryWrapper entry = entries[entryIndex]; ITypedElement searchParameterElement = entry.Resource; var searchParameter = new SearchParameterWrapper(searchParameterElement); // If this is a composite search parameter, then make sure components are defined. if (string.Equals(searchParameter.Type, SearchParamType.Composite.GetLiteral(), StringComparison.OrdinalIgnoreCase)) { var composites = searchParameter.Component; if (composites.Count == 0) { AddIssue(Core.Resources.SearchParameterDefinitionInvalidComponent, searchParameter.Url); continue; } for (int componentIndex = 0; componentIndex < composites.Count; componentIndex++) { ITypedElement component = composites[componentIndex]; var definitionUrl = GetComponentDefinition(component); if (definitionUrl == null || !_uriDictionary.TryGetValue(new Uri(definitionUrl), out SearchParameterInfo componentSearchParameter)) { AddIssue( Core.Resources.SearchParameterDefinitionInvalidComponentReference, searchParameter.Url, componentIndex); continue; } if (componentSearchParameter.Type == SearchParamType.Composite) { AddIssue( Core.Resources.SearchParameterDefinitionComponentReferenceCannotBeComposite, searchParameter.Url, componentIndex); continue; } if (string.IsNullOrWhiteSpace(component.Scalar("expression")?.ToString())) { AddIssue( Core.Resources.SearchParameterDefinitionInvalidComponentExpression, searchParameter.Url, componentIndex); continue; } } } // Make sure the base is defined. var bases = searchParameter.Base; if (bases.Count == 0) { AddIssue(Core.Resources.SearchParameterDefinitionBaseNotDefined, searchParameter.Url); continue; } for (int baseElementIndex = 0; baseElementIndex < bases.Count; baseElementIndex++) { var code = bases[baseElementIndex]; string baseResourceType = code; // Make sure the expression is not empty unless they are known to have empty expression. // These are special search parameters that searches across all properties and needs to be handled specially. if (ShouldExcludeEntry(baseResourceType, searchParameter.Name) || (_modelInfoProvider.Version == FhirSpecification.R5 && _knownBrokenR5.Contains(new Uri(searchParameter.Url)))) { continue; } else { if (string.IsNullOrWhiteSpace(searchParameter.Expression)) { AddIssue(Core.Resources.SearchParameterDefinitionInvalidExpression, searchParameter.Url); continue; } } validatedSearchParameters.Add((baseResourceType, CreateSearchParameterInfo(searchParameter))); } } EnsureNoIssues(); return(validatedSearchParameters); void AddIssue(string format, params object[] args) { issues.Add(new OperationOutcomeIssue( OperationOutcomeConstants.IssueSeverity.Fatal, OperationOutcomeConstants.IssueType.Invalid, string.Format(CultureInfo.InvariantCulture, format, args))); } void EnsureNoIssues() { if (issues.Count != 0) { throw new InvalidDefinitionException( Core.Resources.SearchParameterDefinitionContainsInvalidEntry, issues.ToArray()); } } }