public void TestFhirUri_OperationResourceInstance(FhirVersion fhirVersion, string serversBase, string requestBase, string resourceName, string resourceId, string operationName, string query) { // Prepare FhirUriFactory FhirUriFactory = GetFhirUriFactory(serversBase, new string[] { resourceName }); string RequestUrl = $"{requestBase}/{resourceName}/{resourceId}/${operationName}?{query}"; //Act if (FhirUriFactory.TryParse(RequestUrl, fhirVersion, out IFhirUri? IFhirUri, out string ErrorMessage)) { //Assert if (IFhirUri is object) { Assert.Equal(operationName, IFhirUri.OperationName); Assert.Equal(OperationScope.Instance, IFhirUri.OperationType); Assert.Equal(resourceName, IFhirUri.ResourseName); Assert.Equal(resourceId, IFhirUri.ResourceId); Assert.False(IFhirUri.IsContained); Assert.True(IFhirUri.IsRelativeToServer); Assert.Equal(new Uri(serversBase), IFhirUri.UriPrimaryServiceRoot); Assert.False(IFhirUri.IsHistoryReferance); Assert.Equal(string.Empty, IFhirUri.VersionId); Assert.Null(IFhirUri.PrimaryServiceRootRemote); Assert.Equal(new Uri(serversBase), IFhirUri.PrimaryServiceRootServers); Assert.False(IFhirUri.IsCompartment); Assert.False(IFhirUri.ErrorInParseing); Assert.False(IFhirUri.IsMetaData); Assert.False(IFhirUri.IsCompartment); Assert.False(IFhirUri.IsUrn); Assert.False(IFhirUri.IsFormDataSearch); Assert.Equal(RequestUrl, IFhirUri.OriginalString); Assert.Equal(string.Empty, IFhirUri.CompartmentalisedResourseName); Assert.Equal(fhirVersion, IFhirUri.FhirVersion); Assert.Equal(query, IFhirUri.Query); Assert.Equal(string.Empty, IFhirUri.Urn); Assert.Null(IFhirUri.UrnType); Assert.Equal(string.Empty, IFhirUri.ParseErrorMessage); } } else { Assert.Equal("some error message", ErrorMessage); } }
public void TestFhirUriCanonical(FhirVersion fhirVersion, string resourceName, string resourceId, string CanonicalVersionId) { // Prepare FhirUriFactory FhirUriFactory = GetFhirUriFactory(TestData.BaseUrlServer, new string[] { resourceName }); string RequestUrl = $"{resourceName}/{resourceId}|{CanonicalVersionId}"; //Act if (FhirUriFactory.TryParse(RequestUrl, fhirVersion, out IFhirUri? IFhirUri, out string ErrorMessage)) { //Assert if (IFhirUri is object) { Assert.Equal(resourceName, IFhirUri.ResourseName); Assert.Equal(resourceId, IFhirUri.ResourceId); Assert.Equal(string.Empty, IFhirUri.VersionId); Assert.Equal(CanonicalVersionId, IFhirUri.CanonicalVersionId); Assert.Equal(new Uri(TestData.BaseUrlServer), IFhirUri.PrimaryServiceRootServers); Assert.False(IFhirUri.IsCompartment); Assert.False(IFhirUri.ErrorInParseing); Assert.False(IFhirUri.IsMetaData); Assert.False(IFhirUri.IsOperation); Assert.False(IFhirUri.IsCompartment); Assert.False(IFhirUri.IsUrn); Assert.False(IFhirUri.IsFormDataSearch); Assert.Equal(RequestUrl, IFhirUri.OriginalString); Assert.Equal(string.Empty, IFhirUri.CompartmentalisedResourseName); Assert.Equal(fhirVersion, IFhirUri.FhirVersion); Assert.Equal(string.Empty, IFhirUri.OperationName); Assert.Null(IFhirUri.OperationType); Assert.Equal(string.Empty, IFhirUri.Query); Assert.Equal(string.Empty, IFhirUri.Urn); Assert.Null(IFhirUri.UrnType); Assert.Equal(string.Empty, IFhirUri.ParseErrorMessage); } } else { Assert.Equal("some error message", ErrorMessage); } }
public SerachQueryServiceOutcome(FhirVersion FhirVersion, ResourceType ResourceContext, IFhirSearchQuery IFhirSearchQuery) { this.FhirVersion = FhirVersion; this.ResourceContext = ResourceContext; this.CountRequested = IFhirSearchQuery.Count; this.PageRequested = IFhirSearchQuery.Page; this.SummaryType = IFhirSearchQuery.SummaryType; this.Contained = IFhirSearchQuery.Contained; this.ContainedType = IFhirSearchQuery.ContainedType; this.Text = IFhirSearchQuery.Text; this.Content = IFhirSearchQuery.Content; this.Filter = IFhirSearchQuery.Filter; this.Query = IFhirSearchQuery.Query; this.InvalidSearchQueryList = IFhirSearchQuery.InvalidParameterList; this.UnsupportedSearchQueryList = new List <InvalidSearchQueryParameter>(); this.IncludeList = new List <SearchQueryInclude>(); this.SearchQueryList = new List <ISearchQueryBase>(); this.HasList = new List <SearchQueryHas>(); }
public void DoubleChainQueryPositive(FhirVersion fhirVersion, ResourceType resourceContext, string parameterName, string parameterValue) { //Prepare SearchQueryService SearchQueryService = SetupSearchQueryService(); Dictionary <string, StringValues> QueryDictonary = new Dictionary <string, StringValues> { { parameterName, new StringValues(parameterValue) }, }; FhirSearchQuery FhirSearchQuery = new FhirSearchQuery(); FhirSearchQuery.Parse(QueryDictonary); //Act ISerachQueryServiceOutcome Outcome = SearchQueryService.Process(fhirVersion, resourceContext, FhirSearchQuery).Result; //Assert Assert.NotNull(Outcome); Assert.Equal(0, Outcome.InvalidSearchQueryList.Count); Assert.Null(Outcome.CountRequested); Assert.Equal(1, Outcome.SearchQueryList.Count); Assert.Equal(Common.Enums.ResourceType.Observation, Outcome.ResourceContext); var ChainSearchQuery = Outcome.SearchQueryList[0]; Assert.NotNull(ChainSearchQuery); Assert.Equal("subject", ChainSearchQuery.Name); Assert.NotNull(ChainSearchQuery.ChainedSearchParameter); Assert.Equal("organization", ChainSearchQuery.ChainedSearchParameter !.Name); Assert.NotNull(ChainSearchQuery.ChainedSearchParameter !.ChainedSearchParameter); Assert.Equal("name", ChainSearchQuery.ChainedSearchParameter !.ChainedSearchParameter !.Name); if (ChainSearchQuery.ChainedSearchParameter !.ChainedSearchParameter is SearchQueryString SearchQueryString) { Assert.Single(SearchQueryString.ValueList); Assert.Equal("acmehealth", SearchQueryString.ValueList[0].Value); } }
public FhirUri(FhirVersion fhirVersion, Uri PrimaryServiceRootServers) { this.PrimaryServiceRootServers = PrimaryServiceRootServers; this.FhirVersion = fhirVersion; this.ParseErrorMessage = string.Empty; this.ErrorInParseing = false; this.ResourseName = string.Empty; this.CompartmentalisedResourseName = string.Empty; this.ResourseName = string.Empty; this.ResourceId = string.Empty; this.VersionId = string.Empty; this.OperationName = string.Empty; this.Query = string.Empty; this.OriginalString = string.Empty; this.IsUrn = false; this.Urn = string.Empty; this.IsFormDataSearch = false; this.IsRelativeToServer = false; this.IsContained = false; this.IsCompartment = false; this.IsMetaData = false; this.IsHistoryReferance = false; this.CanonicalVersionId = string.Empty; }
public static bool CanConvertBetweenVersions(FhirVersion from, FhirVersion to) { int versionHops = Math.Abs(to - from); return(MAX_VERSION_HOPS == versionHops); }
private static FhirLookupTemplateProcessor <Observation> GetFhirTemplateProcessor(FhirVersion fhirVersion) { switch (fhirVersion) { case FhirVersion.R4: return(new R4FhirLookupTemplateProcessor()); default: throw new NotImplementedException(); } throw new NotImplementedException(); }
public static string GetFhirVersionAsString(this FhirVersion version) { return(FhirConstants.KnownFhirVersions[version]); }
public static bool IsVersionSupported(FhirVersion version) { return(SupportedVersions.Contains(version)); }
public async Task <ChainQueryProcessingOutcome> Process(FhirVersion fhirVersion, ResourceType resourceContext, KeyValuePair <string, StringValues> Parameter) { this.FhirVersion = fhirVersion; this.ResourceContext = resourceContext; var Outcome = new ChainQueryProcessingOutcome(); this.RawParameter = $"{Parameter.Key}={Parameter.Value}"; string[] ChaimedParameterSplit = Parameter.Key.Split(FhirSearchQuery.TermChainDelimiter); for (int i = 0; i < ChaimedParameterSplit.Length; i++) { //Each segment in the chain is a IsChainedReferance except the last segment in the chain which has the value. bool IsChainedReferance = !(i == ChaimedParameterSplit.Length - 1); Bug.Logic.DomainModel.SearchParameter?SearchParameter = null; string ParameterNameWithModifier = Parameter.Key.Split(FhirSearchQuery.TermChainDelimiter)[i]; StringValues ParameterValue = string.Empty; //There is no valid Value for a chained reference parameter unless it is the last in a series //of chains, so don't set it unless this is the last parameter in the whole chain. if (i == ChaimedParameterSplit.Count() - 1) { ParameterValue = Parameter.Value; } var SingleChainedParameter = new KeyValuePair <string, StringValues>(ParameterNameWithModifier, ParameterValue); string ParameterName = string.Empty; string ParameterModifierTypedResource = string.Empty; //Check for and deal with modifiers e.g 'Patient' in the example: subject:Patient.family=millar if (ParameterNameWithModifier.Contains(FhirSearchQuery.TermSearchModifierDelimiter)) { string[] ParameterModifierSplit = ParameterNameWithModifier.Split(FhirSearchQuery.TermSearchModifierDelimiter); ParameterName = ParameterModifierSplit[0].Trim(); if (ParameterModifierSplit.Length > 1) { ResourceType?ModifierResourceType = IResourceTypeSupport.GetTypeFromName(ParameterModifierSplit[1].Trim()); if (ModifierResourceType.HasValue && IKnownResource.IsKnownResource(this.FhirVersion, ParameterModifierSplit[1].Trim())) { ParameterModifierTypedResource = ParameterModifierSplit[1].Trim(); } else { ErrorInSearchParameterProcessing = true; //If the Parent is ok then we can assume that any error further down the chain is an invalid search term rather than an unsupported term //as it is clear that this is a FHIR search term and not some other search parameter forgen to FHIR if (ParentChainSearchParameter is object) { InvalidSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, $"The resource type modifier: {ParameterModifierSplit[1].Trim()} within the chained search query of {this.RawParameter} is not a known resource for FHIR version: {this.FhirVersion.GetCode()} within this server")); } else { //Here we are only looking up the ParameterName to check weather this should be an unsupported parameter or an invalid parameter. //If we know the ParameterName then it is invalid whereas if we don't then it is unsupported and both are not known. List <Bug.Logic.DomainModel.SearchParameter> TempSearchParameterList = await ISearchParameterCache.GetForIndexingAsync(this.FhirVersion, this.ResourceContext); var TempSearchParameter = TempSearchParameterList.SingleOrDefault(x => x.Name == ParameterName); if (TempSearchParameter is null) { string Message = $"Both the search parameter name: {ParameterName} for the resource type: {this.ResourceContext.GetCode()} and its resource type modifier: {ParameterModifierSplit[1].Trim()} within the chained search query of {this.RawParameter} are unsupported within this server for FHIR version: {this.FhirVersion.GetCode()}."; UnsupportedSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, Message)); } else { InvalidSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, $"The resource type modifier: {ParameterModifierSplit[1].Trim()} within the chained search query of {this.RawParameter} is not a known resource type for this server and FHIR version {this.FhirVersion.GetCode()}.")); } } break; } } } else { ParameterName = ParameterNameWithModifier; } SearchParameter = await GetSearchParameter(ParameterName); //We have no resolved a SearchParameter so we parse the value if it is the end of the chain, see IsChainedReferance //or we are only parsing as a chain segment with no end value if (SearchParameter != null) { //If this is the last parameter in the chain then treat is as not a chain, otherwise treat as a chain await SetChain(SearchParameter, SingleChainedParameter, IsChainedReferance); } else { ErrorInSearchParameterProcessing = true; if (this.InvalidSearchQueryParameterList.Count == 0 && this.UnsupportedSearchQueryParameterList.Count == 0) { throw new ApplicationException("Internal Server Error: When processing a chain search query we failed to resolve a search parameter for the query string however their are " + $"no items found in either the {nameof(InvalidSearchQueryParameterList)} or the {nameof(UnsupportedSearchQueryParameterList)}. This is an error in its self."); } break; } } //End of Chain loop if (!ErrorInSearchParameterProcessing) { if (ParentChainSearchParameter is object) { Outcome !.SearchQueryList.Add(ParentChainSearchParameter); return(Outcome); } else { throw new NullReferenceException(nameof(PreviousChainSearchParameter)); } } else { InvalidSearchQueryParameterList.ForEach(x => Outcome !.InvalidSearchQueryList.Add(x)); UnsupportedSearchQueryParameterList.ForEach(x => Outcome !.UnsupportedSearchQueryList.Add(x)); return(Outcome); } }
public void Is_FhirVersion_Supported(FhirVersion version) { Assert.True(FhirConverter.IsVersionSupported(version)); }
public void TestFhirUriHistory(FhirVersion fhirVersion, string serversBase, string requestBase, string resourceName, string resourceId, string versionId) { // Prepare FhirUriFactory FhirUriFactory = GetFhirUriFactory(serversBase, new string[] { resourceName }); string RequestUrl; if (!string.IsNullOrWhiteSpace(versionId)) { RequestUrl = $"{resourceName}/{resourceId}/_history/{versionId}"; } else { if (!string.IsNullOrWhiteSpace(resourceId)) { RequestUrl = $"{resourceName}/{resourceId}"; } else { RequestUrl = $"{resourceName}"; } } if (!string.IsNullOrWhiteSpace(requestBase)) { RequestUrl = $"{requestBase}/{RequestUrl}"; } //Act if (FhirUriFactory.TryParse(RequestUrl, fhirVersion, out IFhirUri? IFhirUri, out string ErrorMessage)) { //Assert if (IFhirUri is object) { Assert.Equal(resourceName, IFhirUri.ResourseName); if (!string.IsNullOrWhiteSpace(resourceId)) { if (resourceId.StartsWith('#')) { Assert.True(IFhirUri.IsContained); Assert.Equal(resourceId.TrimStart('#'), IFhirUri.ResourceId); } else { Assert.False(IFhirUri.IsContained); Assert.Equal(resourceId, IFhirUri.ResourceId); } } else { Assert.Equal(string.Empty, IFhirUri.ResourceId); } if (!string.IsNullOrWhiteSpace(versionId)) { Assert.True(IFhirUri.IsHistoryReferance); Assert.Equal(versionId, IFhirUri.VersionId); } else { Assert.False(IFhirUri.IsHistoryReferance); Assert.Equal(string.Empty, IFhirUri.VersionId); } if (serversBase == requestBase) { Assert.Null(IFhirUri.PrimaryServiceRootRemote); Assert.True(IFhirUri.IsRelativeToServer); Assert.Equal(new Uri(requestBase), IFhirUri.UriPrimaryServiceRoot); } else { if (!string.IsNullOrWhiteSpace(requestBase)) { Assert.NotNull(IFhirUri.PrimaryServiceRootRemote); Assert.False(IFhirUri.IsRelativeToServer); Assert.Equal(new Uri(requestBase), IFhirUri.PrimaryServiceRootRemote); } else { Assert.Null(IFhirUri.PrimaryServiceRootRemote); Assert.True(IFhirUri.IsRelativeToServer); } } Assert.Equal(new Uri(serversBase), IFhirUri.PrimaryServiceRootServers); Assert.False(IFhirUri.IsCompartment); Assert.False(IFhirUri.ErrorInParseing); Assert.False(IFhirUri.IsMetaData); Assert.False(IFhirUri.IsOperation); Assert.False(IFhirUri.IsCompartment); Assert.False(IFhirUri.IsUrn); Assert.False(IFhirUri.IsFormDataSearch); Assert.Equal(RequestUrl, IFhirUri.OriginalString); Assert.Equal(string.Empty, IFhirUri.CompartmentalisedResourseName); Assert.Equal(fhirVersion, IFhirUri.FhirVersion); Assert.Equal(string.Empty, IFhirUri.OperationName); Assert.Null(IFhirUri.OperationType); Assert.Equal(string.Empty, IFhirUri.Query); Assert.Equal(string.Empty, IFhirUri.Urn); Assert.Null(IFhirUri.UrnType); Assert.Equal(string.Empty, IFhirUri.ParseErrorMessage); } } else { Assert.Equal("some error message", ErrorMessage); } }
private DirectoryInfo CreateBaseDirectory(Uri uri, FhirVersion fhirVersion) { var path = Path.Combine(SafeDirectoryName(uri.Host), SafeFilename(fhirVersion.GetFhirVersionAsString())); return(Directory.CreateDirectory(path)); }
public FhirVersionFatalException(FhirVersion fhirMajorVersion) { HttpStatusCode = HttpStatusCode.InternalServerError; MessageList = new string[] { $"A FhirMajorVersion was not handled by the server. The FhirMajorVersion value literal was: {fhirMajorVersion.GetCode()}" }; }
public static ResourceTypeWrapper ResourceType(this Resource it, FhirVersion v) { var wrapper = new ResourceWrapper(it, v); return(wrapper.ResourceType); }
public static void SerializeResourceToDiskAsJson(this Resource resource, string path, FhirVersion version, bool pretty = true) { switch (version) { case FhirVersion.R3: SerializeResourceToDiskAsJsonR3(resource, path, pretty); break; case FhirVersion.R4: SerializeResourceToDiskAsJsonR4(resource, path, pretty); break; } }
public FhirApiResourceQuery(HttpVerb HttpVerb, FhirVersion FhirVersion, Uri RequestUri, Dictionary <string, StringValues> RequestQuery, Dictionary <string, StringValues> HeaderDictionary, string ResourceName) : base(HttpVerb, FhirVersion, RequestUri, RequestQuery, HeaderDictionary) { this.ResourceName = ResourceName; }
private Task HandleExceptionAsync(HttpContext context, Exception exec, ILogger <ErrorHandlingMiddleware> _logger) { _logger.LogError(exec, exec.Message); FhirVersion VersionInUse = GetFhirVersionInUse(context.Request.Path.Value); if (exec is FhirException FhirException) { _logger.LogError(FhirException, "FhirException has been thrown"); FhirFormatType AcceptFormatType = Bug.Api.ContentFormatters.FhirMediaType.GetFhirFormatTypeFromAcceptHeader(context.Request.Headers.SingleOrDefault(x => x.Key.ToLower(System.Globalization.CultureInfo.CurrentCulture) == "accept").Value); switch (VersionInUse) { case FhirVersion.Stu3: { return(Stu3FhirExceptionProcessing(context, FhirException, AcceptFormatType)); } case FhirVersion.R4: { return(R4FhirExceptionProcessing(context, FhirException, AcceptFormatType)); } default: throw new ApplicationException($"Unable to resolve which major version of FHIR is in use. Found enum: {VersionInUse.ToString()}"); } } else { string ErrorGuid = Common.FhirTools.FhirGuidSupport.NewFhirGuid(); string UsersErrorMessage = string.Empty; if (Debugger.IsAttached) { UsersErrorMessage = $"{System.Text.Encodings.Web.HtmlEncoder.Default.Encode(exec.ToString())} -> Server Error log identifier: {ErrorGuid}"; } else { UsersErrorMessage = $"An unhanded exception has been thrown. To protect data privacy the exception information has been written to the application log with the error log identifier: {ErrorGuid}"; } _logger.LogError(exec, $"Error log identifier: {ErrorGuid}"); switch (VersionInUse) { case FhirVersion.Stu3: { Stu3Model.OperationOutcome Stu3OperationOutcomeResult = IOperationOutComeSupportFactory.GetStu3().GetFatal(new string[] { UsersErrorMessage }); context.Response.ContentType = Bug.Api.ContentFormatters.FhirMediaType.GetMediaTypeHeaderValue(Stu3OperationOutcomeResult.GetType(), FhirFormatType.xml).Value; context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; return(context.Response.WriteAsync(IStu3SerializationToXml.SerializeToXml(Stu3OperationOutcomeResult))); } case FhirVersion.R4: { R4Model.OperationOutcome R4OperationOutcomeResult = IOperationOutComeSupportFactory.GetR4().GetFatal(new string[] { UsersErrorMessage }); context.Response.ContentType = Bug.Api.ContentFormatters.FhirMediaType.GetMediaTypeHeaderValue(R4OperationOutcomeResult.GetType(), FhirFormatType.xml).Value; context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; return(context.Response.WriteAsync(IR4SerializationToXml.SerializeToXml(R4OperationOutcomeResult))); } default: string msg = $"Unable to resolve which major version of FHIR is in use. Found enum: {VersionInUse.ToString()}"; _logger.LogError(msg); throw new ApplicationException(msg); } } }
public IActionResult Post([FromBody] TransformationTestRequest request) { // Validate Request. if (!IsValidRequest(request, out string errorMessage)) { return(this.BadRequest( new TransformationTestResponse() { Result = TestResult.Fail.ToString(), Reason = errorMessage, })); } // Validate mapping semantic. var templateContext = CollectionFhirTemplateFactory.Default.Create(request.FhirMapping); if (!templateContext.IsValid(out string errors)) { return(this.BadRequest( new TransformationTestResponse() { Result = TestResult.Fail.ToString(), Reason = errors, })); } FhirVersion fhirVersion = (FhirVersion)Enum.Parse(typeof(FhirVersion), request.FhirVersion, true); FhirIdentityResolutionType fhirIdentityResolutionType = (FhirIdentityResolutionType)Enum.Parse(typeof(FhirIdentityResolutionType), request.FhirIdentityResolutionType, true); IMeasurementGroup measurementGroup; try { measurementGroup = JToken.Parse(request.NormalizedData).ToObject <MeasurementGroup>(); if (string.IsNullOrWhiteSpace(measurementGroup.DeviceId)) { return(this.BadRequest( new TransformationTestResponse() { Result = TestResult.Fail.ToString(), Reason = "Device Id can't be null or empty.", })); } if (fhirIdentityResolutionType == FhirIdentityResolutionType.Create && string.IsNullOrWhiteSpace(measurementGroup.PatientId)) { return(this.BadRequest( new TransformationTestResponse() { Result = TestResult.Fail.ToString(), Reason = "Patient Id can't be null with identity resolution type as \"Create\".", })); } } catch (Exception ex) { return(this.BadRequest( new TransformationTestResponse() { Result = TestResult.Fail.ToString(), Reason = ex.Message, })); } // Start processing. try { FhirLookupTemplateProcessor <Observation> processor = GetFhirTemplateProcessor(fhirVersion); var grps = processor.CreateObservationGroups(templateContext.Template, measurementGroup); Observation observation = null; string deviceId = measurementGroup.DeviceId; string patientId = fhirIdentityResolutionType == FhirIdentityResolutionType.Create ? measurementGroup.PatientId : PatientIdPlaceholder; foreach (var grp in grps) { if (observation == null) { observation = processor.CreateObservation(templateContext.Template, grp); observation.Subject = patientId.ToReference <Patient>(); observation.Device = deviceId.ToReference <Device>(); var identity = GenerateObservationId(grp, deviceId, patientId); var observerationId = new Identifier { System = identity.System, Value = identity.Identifer, }; observation.Identifier = new List <Identifier> { observerationId }; } else { observation = processor.MergeObservation(templateContext.Template, grp, observation); } } return(this.Ok( new TransformationTestResponse() { Result = TestResult.Success.ToString(), FhirData = observation.ToJson(new FhirJsonSerializationSettings() { Pretty = true, }), })); } catch (Exception ex) { return(this.BadRequest( new TransformationTestResponse() { Result = TestResult.Fail.ToString(), Reason = ex.Message, })); } }
public void TestFhirUri_ResourceNameValidForFhirVersion(FhirVersion fhirVersion, string serversBase, string resourceNameR4, string resourceNameStu3, string resourceId) { // Prepare Mock <IServiceBaseUrlConfi> IServiceBaseUrlMock = IServiceBaseUrl_MockFactory.Get(serversBase, serversBase); Mock <IR4ValidateResourceName> IR4ValidateResourceNameMock = IR4ValidateResourceName_MockFactory.Get(new string[] { resourceNameR4 }); Mock <IStu3ValidateResourceName> IStu3ValidateResourceNameMock = IStu3ValidateResourceName_MockFactory.Get(new string[] { resourceNameStu3 }); Mock <IValidateResourceNameFactory> IValidateResourceNameFactoryMock = IValidateResourceNameFactory_MockFactory.Get(IStu3ValidateResourceNameMock.Object, IR4ValidateResourceNameMock.Object); FhirUriFactory FhirUriFactory = new FhirUriFactory(IServiceBaseUrlMock.Object, IValidateResourceNameFactoryMock.Object); string RequestUrl; if (fhirVersion == FhirVersion.Stu3) { RequestUrl = $"{resourceNameStu3}/{resourceId}"; } else { RequestUrl = $"{resourceNameR4}/{resourceId}"; } //Act if (FhirUriFactory.TryParse(RequestUrl, fhirVersion, out IFhirUri? IFhirUri, out string ErrorMessage)) { //Assert if (IFhirUri is object) { if (fhirVersion == FhirVersion.Stu3) { Assert.Equal(resourceNameStu3, IFhirUri.ResourseName); } else { Assert.Equal(resourceNameR4, IFhirUri.ResourseName); } Assert.Equal(fhirVersion, IFhirUri.FhirVersion); Assert.False(IFhirUri.IsContained); Assert.Equal(resourceId.TrimStart('#'), IFhirUri.ResourceId); Assert.True(IFhirUri.IsRelativeToServer); Assert.Equal(new Uri(serversBase), IFhirUri.UriPrimaryServiceRoot); Assert.False(IFhirUri.IsHistoryReferance); Assert.Equal(string.Empty, IFhirUri.VersionId); Assert.Null(IFhirUri.PrimaryServiceRootRemote); Assert.Equal(new Uri(serversBase), IFhirUri.PrimaryServiceRootServers); Assert.False(IFhirUri.IsCompartment); Assert.False(IFhirUri.ErrorInParseing); Assert.False(IFhirUri.IsMetaData); Assert.False(IFhirUri.IsOperation); Assert.False(IFhirUri.IsCompartment); Assert.False(IFhirUri.IsUrn); Assert.False(IFhirUri.IsFormDataSearch); Assert.Equal(RequestUrl, IFhirUri.OriginalString); Assert.Equal(string.Empty, IFhirUri.CompartmentalisedResourseName); Assert.Equal(string.Empty, IFhirUri.OperationName); Assert.Null(IFhirUri.OperationType); Assert.Equal(string.Empty, IFhirUri.Query); Assert.Equal(string.Empty, IFhirUri.Urn); Assert.Null(IFhirUri.UrnType); Assert.Equal(string.Empty, IFhirUri.ParseErrorMessage); } else { Assert.Equal("some error message", ErrorMessage); } } }
public HistoryInstanceQuery(HttpVerb HttpVerb, FhirVersion FhirVersion, Uri RequestUri, Dictionary <string, StringValues> RequestQuery, Dictionary <string, StringValues> HeaderDictionary, string ResourceName, string ResourceId) : base(HttpVerb, FhirVersion, RequestUri, RequestQuery, HeaderDictionary, ResourceName, ResourceId) { }
public void CanConvert_Between_FhirVersion_WithOneHop(FhirVersion from, FhirVersion to) { Assert.True(FhirConverter.CanConvertBetweenVersions(from, to)); }
private async Task <Bug.Logic.DomainModel.SearchParameter?> GetSearchParameter(string parameterName) { Bug.Logic.DomainModel.SearchParameter SearchParameter; List <Bug.Logic.DomainModel.SearchParameter> SearchParameterList = await ISearchParameterCache.GetForIndexingAsync(this.FhirVersion, this.ResourceContext); //Here we go through a series of ways to locate the SearchParameter for each segment of the chain query if (PreviousChainSearchParameter is null) { //If there is no previous then we look through the search parameter for the root resource type stored in this.ResourceContext SearchParameter = SearchParameterList.SingleOrDefault(x => x.Name == parameterName); if (SearchParameter is null) { ErrorInSearchParameterProcessing = true; UnsupportedSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, $"The resource search parameter name of: {parameterName} within the chained search query of: {this.RawParameter} is not a known search parameter for the resource: {this.ResourceContext} for this server in FHIR version: {this.FhirVersion.GetCode()}")); return(null); } else { return(SearchParameter); } } else { //Here we are using the PreviousChainSearchParameter's TypeModifierResource as the context to find the search parameter if (!PreviousChainSearchParameter.TypeModifierResource.HasValue) { //If there is no TypeModifierResource on the previous then we look at how many it supports and if only one we can use that. if (PreviousChainSearchParameter.TargetResourceTypeList.Count == 1) { PreviousChainSearchParameter.TypeModifierResource = PreviousChainSearchParameter.TargetResourceTypeList.ToArray()[0].ResourceTypeId; List <Bug.Logic.DomainModel.SearchParameter> SearchParametersListForTarget = await ISearchParameterCache.GetForIndexingAsync(this.FhirVersion, PreviousChainSearchParameter.TargetResourceTypeList.ToArray()[0].ResourceTypeId); Bug.Logic.DomainModel.SearchParameter SearchParameterForTarget = SearchParametersListForTarget.SingleOrDefault(x => x.Name == parameterName); if (SearchParameterForTarget is null) { string Message = $"Unable to locate the search parameter named: {parameterName} for the resource type: {PreviousChainSearchParameter.TypeModifierResource} for FHIR version: {this.FhirVersion.GetCode()} within the chain search query of: {this.RawParameter}"; ErrorInSearchParameterProcessing = true; InvalidSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, Message)); return(null); } else { SearchParameter = SearchParameterForTarget; return(SearchParameter); } } else { //If more than one then we search for the given search parameter name among all resource types supported for the PreviousChainSearchParameter Dictionary <ResourceType, Bug.Logic.DomainModel.SearchParameter> MultiChainedSearchParameter = new Dictionary <ResourceType, DomainModel.SearchParameter>(); foreach (var TargetResourceType in PreviousChainSearchParameter.TargetResourceTypeList) { List <Bug.Logic.DomainModel.SearchParameter> SearchParametersListForTarget = await ISearchParameterCache.GetForIndexingAsync(this.FhirVersion, TargetResourceType.ResourceTypeId); Bug.Logic.DomainModel.SearchParameter SearchParameterForTarget = SearchParametersListForTarget.SingleOrDefault(x => x.Name == parameterName); if (SearchParameterForTarget != null) { MultiChainedSearchParameter.Add(TargetResourceType.ResourceTypeId, SearchParameterForTarget); } } if (MultiChainedSearchParameter.Count() == 1) { //If this resolves to only one found then we use it PreviousChainSearchParameter.TypeModifierResource = MultiChainedSearchParameter.First().Key; SearchParameter = MultiChainedSearchParameter.First().Value; return(SearchParameter); } else { if (MultiChainedSearchParameter.Count > 1) { //We still have many to choose from so it cannot be resolved. The user need to specify the ResourceType with the Type modifier on the search parameter query e.g subject:Patient.family string RefResources = string.Empty; foreach (var DicItem in MultiChainedSearchParameter) { RefResources += ", " + DicItem.Key.GetCode(); } string ResourceName = this.ResourceContext.GetCode(); string Message = string.Empty; Message = $"The chained search parameter '{this.RawParameter}' is ambiguous. "; Message += $"Additional information: "; Message += $"The search parameter '{parameterName}' could be a search parameter for any of the following resource types ({RefResources.TrimStart(',').Trim()}). "; Message += $"To correct this you must prefix the search parameter with a Type modifier, for example: '{PreviousChainSearchParameter.Name}:{MultiChainedSearchParameter.First().Key.GetCode()}.{MultiChainedSearchParameter.First().Value.Name}' "; Message += $"If the '{MultiChainedSearchParameter.First().Key.GetCode()}' resource was the intended reference for the search parameter '{MultiChainedSearchParameter.First().Value.Name}'."; ErrorInSearchParameterProcessing = true; InvalidSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, Message)); return(null); } else { //We have found zero matches for this search parameter name from the previous allowed resource types, so the search parameter name is possibly wrong. string TargetResourceTypes = string.Empty; foreach (var TargetResourceType in PreviousChainSearchParameter.TargetResourceTypeList) { TargetResourceTypes += ", " + TargetResourceType.ResourceTypeId.GetCode(); } string ResourceName = this.ResourceContext.GetCode(); string Message = string.Empty; Message = $"The chained search parameter '{this.RawParameter}' is unresolvable. "; Message += $"Additional information: "; Message += $"The search parameter: {parameterName} should be a search parameter for any of the following resource types ({TargetResourceTypes.TrimStart(',').Trim()}) as resolved from the previous link in the chain: {PreviousChainSearchParameter.Name}. "; Message += $"To correct this you must specify a search parameter here that is supported by those resource types. "; Message += $"Please review your chained search query and specifically the use of the search parameter: {parameterName}'"; ErrorInSearchParameterProcessing = true; InvalidSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, Message)); return(null); } } } } else if (CheckModifierTypeResourceValidForSearchParameter(PreviousChainSearchParameter.TypeModifierResource.Value, PreviousChainSearchParameter.TargetResourceTypeList)) { //PreviousChainSearchParameter.TypeModifierResource = PreviousChainSearchParameter.TypeModifierResource; //Double check the final Type modifier resource resolved is valid for the previous search parameter, the user could have got it wrong in the query. ResourceType ResourceTypeTest = PreviousChainSearchParameter.TypeModifierResource.Value; FhirVersion FhirVersionTest = this.FhirVersion; var TempSearchParameterList = await this.ISearchParameterCache.GetForIndexingAsync(FhirVersionTest, ResourceTypeTest); SearchParameter = TempSearchParameterList.SingleOrDefault(x => x.Name == parameterName); if (SearchParameter is object) { return(SearchParameter); } else { string ResourceName = ResourceTypeTest.GetCode(); string Message = $"The chained search query part: {parameterName} is not a supported search parameter name for the resource type: {ResourceName} for this server in FHIR version {this.FhirVersion.GetCode()}. "; Message += $"Additional information: "; Message += $"This search parameter was a chained search parameter. The part that was not recognized was: {parameterName}."; ErrorInSearchParameterProcessing = true; InvalidSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, Message)); return(null); } } else { //The modifier target resource provided is not valid for the previous reference, e.g subject:DiagnosticReport.family=millar string ResourceName = this.ResourceContext.GetCode(); string Message = $"The search parameter '{parameterName}' is not supported by this server for the resource type '{ResourceName}'. "; Message += $"Additional information: "; Message += $"This search parameter was a chained search parameter. The part that was not recognized was '{PreviousChainSearchParameter.Name}.{parameterName}', The search parameter modifier given '{PreviousChainSearchParameter.TypeModifierResource}' is not valid for the search parameter {PreviousChainSearchParameter.Name}. "; ErrorInSearchParameterProcessing = true; InvalidSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, Message)); return(null); } } }
public async Task AddLocationAsync(Dictionary <string, StringValues> Headers, FhirVersion fhirVersion, string scheme, string resourceId, int versionId) { var ServiceBaseUrl = await IServiceBaseUrlCache.GetPrimaryAsync(fhirVersion); Headers.Add(HeaderNames.Location, $"{scheme}://{ServiceBaseUrl.Url}/{resourceId}/_history/{versionId.ToString()}"); }
public void FhirVersion_Matches_Version_Of_FhirType(FhirVersion expected, Type fhirType) { Assert.Equal(expected, FhirConverter.GetFhirVersion(fhirType)); }
public VReadQuery(HttpVerb HttpVerb, FhirVersion FhirVersion, Uri RequestUri, Dictionary <string, StringValues> RequestQuery, Dictionary <string, StringValues> HeaderDictionary, string ResourceName, string ResourceId, int VersionId) : base(HttpVerb, FhirVersion, RequestUri, RequestQuery, HeaderDictionary, ResourceName, ResourceId, VersionId) { }
public void FhirVersion_Is_Not_Supported(FhirVersion version) { Assert.False(FhirConverter.IsVersionSupported(version)); }
public Uri Url(FhirVersion fhirMajorVersion) { return(ConstructFullUrl(fhirMajorVersion)); }
public void CannotConvert_Between_FhirVersion_WithMoreThanOneHop(FhirVersion from, FhirVersion to) { Assert.False(FhirConverter.CanConvertBetweenVersions(from, to)); }
public void TestFhirUri_Compartment(FhirVersion fhirVersion, string serversBase, string requestBase, string resourceName, string resourceId, string compartmentName, string query) { // Prepare //hit: the resource is unknown because we do not pass it into the GetFhirUriFactory below, we only pass in the resourceName and not the compatmentName FhirUriFactory FhirUriFactory; if (compartmentName == "Unknown") { FhirUriFactory = GetFhirUriFactory(serversBase, new string[] { resourceName }); } else { FhirUriFactory = GetFhirUriFactory(serversBase, new string[] { resourceName, compartmentName }); } string RequestUrl; if (string.IsNullOrWhiteSpace(query)) { RequestUrl = $"{requestBase}/{resourceName}/{resourceId}/{compartmentName}"; } else { RequestUrl = $"{requestBase}/{resourceName}/{resourceId}/{compartmentName}?{query}"; } //Act if (FhirUriFactory.TryParse(RequestUrl, fhirVersion, out IFhirUri? IFhirUri, out string ErrorMessage)) { //Assert if (IFhirUri is object) { Assert.Equal(string.Empty, IFhirUri.OperationName); Assert.Null(IFhirUri.OperationType); Assert.Equal(resourceName, IFhirUri.ResourseName); Assert.Equal(resourceId, IFhirUri.ResourceId); Assert.False(IFhirUri.IsContained); Assert.True(IFhirUri.IsRelativeToServer); Assert.Equal(new Uri(serversBase), IFhirUri.UriPrimaryServiceRoot); Assert.False(IFhirUri.IsHistoryReferance); Assert.Equal(string.Empty, IFhirUri.VersionId); Assert.Null(IFhirUri.PrimaryServiceRootRemote); Assert.Equal(new Uri(serversBase), IFhirUri.PrimaryServiceRootServers); Assert.True(IFhirUri.IsCompartment); Assert.Equal(compartmentName, IFhirUri.CompartmentalisedResourseName); Assert.False(IFhirUri.ErrorInParseing); Assert.False(IFhirUri.IsMetaData); Assert.False(IFhirUri.IsUrn); Assert.False(IFhirUri.IsFormDataSearch); Assert.Equal(RequestUrl, IFhirUri.OriginalString); Assert.Equal(compartmentName, IFhirUri.CompartmentalisedResourseName); Assert.True(IFhirUri.IsCompartment); Assert.Equal(fhirVersion, IFhirUri.FhirVersion); Assert.Equal(string.Empty, IFhirUri.Urn); Assert.Null(IFhirUri.UrnType); Assert.Equal(string.Empty, IFhirUri.ParseErrorMessage); if (string.IsNullOrWhiteSpace(query)) { Assert.Equal(string.Empty, IFhirUri.Query); } else { Assert.Equal(query, IFhirUri.Query); } } } else { if (string.IsNullOrWhiteSpace(query)) { Assert.Equal("The URI has extra unknown content near the end of : 'Unknown'. The full URI was: 'http://base/stuff/Patient/10/Unknown'", ErrorMessage); } else { Assert.Equal("The URI has extra unknown content near the end of : 'Unknown'. The full URI was: 'http://base/stuff/Patient/10/Unknown?query_one=one, query_two=two'", ErrorMessage); } } }